none
继续提问!!《C#入门经典》第12章初涉泛型!迷惑重重,求详细注释解答! RRS feed

  • 问题

  • 需要注释解答的地方我一般都标记了???号!谢谢啦!一共有2个代码块!!!

    using System;
    
    
    
    using System.Collections.Generic;
    
    
    
    using System.Text;
    
    
    
    
    
    
    
    namespace Ch12Ex01
    
    
    
    {
    
    
    
     public class Vector // 建立Vector类,这个类用来计算矢量,即有“角度”和“长度”两个要素。
    
    
    
     {
    
    
    
     public double? R=null; //可空的double型变量R,R初始化为null,R表示二维空间里的“角度”。
    
    
    
     public double? Theta=null;//可空的double型变量Theta,Theta初始化为null,Theta表示“长度”。
    
    
    
    
    
    
    
     public Vector(double? r, double? theta)//构造函数Vector有2个参数,分别是r和theta
    
    
    
     {
    
    
    
      if (r < 0) //如果长度r<0,说明r在Y轴的左边。然后把r和theta转化一下再使用。
    
    
    
      {
    
    
    
      r = -r;
    
    
    
      theta += 180;
    
    
    
      }
    
    
    
      theta = theta % 360;
    
    
    
      R = r;   //这个构造函数的作用是当外界使用Vector(double? r, double? theta)时,
    
    
    
      Theta = theta;  //输入的参数r和theta会把值传给字段R和Theta
    
    
    
     }
    
    
    
    
    
    
    
     public double? ThetaRadians //这个ThetaRadians我没有办法取名字,根据它的返回值
    
    
    
     {    //return (Theta * Math.PI / 180)判断,是得到一个如果
    
    
    
      get   //继续乘以半径R就能得到扇形弧长的东东。。。???
    
    
    
      {
    
    
    
      return (Theta * Math.PI / 180);
    
    
    
      }
    
    
    
      
    
    
    
     }//下面这段不理解,MSDN上页没有合适的讲解。。。???求补充
    
    
    
     public static Vector operator +(Vector op1, Vector op2)
    
    
    
     {
    
    
    
      try//这段异常完全不懂,求详细补充???
    
    
    
      {
    
    
    
      double newX=op1 .R.Value*Math.Sin(op1.ThetaRadians.Value)
    
    
    
       +op2.R.Value *Math.Sin (op2.ThetaRadians .Value );
    
    
    
      double newY = op1.R.Value * Math.Cos(op1.ThetaRadians.Value)
    
    
    
       + op2.R.Value * Math.Cos(op2.ThetaRadians.Value);
    
    
    
      double newR = Math.Sqrt(newX*newX+newY*newY );
    
    
    
      double newTheta = Math.Atan2(newX, newY) * 180 / Math.PI;
    
    
    
      return new Vector(newR, newTheta);
    
    
    
      }
    
    
    
      catch
    
    
    
      {
    
    
    
      return new Vector(null,null);
    
    
    
     
    
    
    
      }
    
    
    
     }
    
    
    
     public static Vector operator -(Vector op1)//不知道这段代码是干嘛用的???
    
    
    
     {
    
    
    
      return new Vector(-op1.R, op1.Theta);
    
    
    
     }
    
    
    
     public static Vector operator -(Vector op1, Vector op2)//不知道这段代码是干嘛用的???
    
    
    
     {
    
    
    
      return op1 + (-op2);
    
    
    
     }
    
    
    
     public override string ToString()//只知道是重写ToString,不明白重写的意义何在???
    
    
    
     {       //HasValue专门用于判断可空类型是否为空
    
    
    
      string rString = R.HasValue ? R.ToString() : "null";//非空则 rString= R.ToString()
    
    
    
      string thetaString = Theta.HasValue ? Theta.ToString() : "null";
    
    
    
      return string.Format("({0} , {1})",rString ,thetaString );
    
    
    
     } 
    
    
    
     }
    
    
    
    }
    
    
    
    
    
    
    
    
    第22222222222222222222222222222222个
    第22222222222222222222222222222222个
    第22222222222222222222222222222222个
    using System;
    
    using System.Collections.Generic;
    
    using System.Linq;
    
    using System.Text;
    
    
    
    namespace Ch12Ex01
    
    {
    
     class Program/*第一次接触在 static void Main(string[] args)之外还有
    
        其他函数的,如下面的 GetVector(string name)
    
         GetNullableDouble()。不知从何问起,求详细注释???//*/
    
     {
    
      static void Main(string[] args)
    
      {
    
       Vector v1 = GetVector("vector1");
    
       Vector v2 = GetVector("vector1");
    
       Console.WriteLine("{0} + {1} = {2}",v1 ,v2,v1+v2);
    
       Console.WriteLine("{0} - {1} = {2}", v1, v2, v1 - v2);
    
       Console.ReadKey();
    
      }
    
      public static Vector GetVector(string name)
    
      {
    
       Console.WriteLine("请输入{0} GetVector",name);
    
       double? r = GetNullableDouble();
    
       Console.WriteLine("请输入{0} in degrees",name);
    
       double? theta = GetNullableDouble();
    
       return new Vector(r, theta);
    
      }
    
      public static double? GetNullableDouble()
    
      {
    
       double? result;
    
       string userInput = Console.ReadLine();
    
       try
    
       {
    
        result = double.Parse(userInput);
    
       }
    
       catch
    
       {
    
        result = null;
    
       }
    
       return result;
    
      }
    
     }
    
    }
    
    
    2010年12月2日 15:45

答案

  • 谢谢大家!不过我感觉解释有些问题还停留在字面意思上!

        比如代码块几处都使用了 operator ,我想问为什么要用operator来重载运算符,而不是

    operator 是什么意思。

        还有try catch语句,我想问的是它的具体流程和每一行的解释,而不是笼统的 抛出异常、抓住异常

    之类的解释。

        总之,我想问的是为什么要这样做,而不是简单的翻译。菜鸟级别,希望大家谅解!


    您好,想问为什么就需要弄清楚需求

    我们都知道1+1=2,可是你的项目需要1+1=1。怎么办?请用操作符重载。回到本例中,通常两个对象是不能直接相加的,正如mazhou解释的那样,为了Vector 实例能相加,达到Vector v3 = v1+v2的效果,才用操作符重载。如果您的需求是不需要两个Vector实例具有相加功能,可以不用操作符重载。这些是需求所决定的。

    try catch的含义是尽量来执行try里的代码块,如果有错误则捕获。如果需要自己来控制错误信息请用try catch,如果不需要控制错误信息,则不用

    编程里的很多语法功能,需要视您的需求而定。也就说需要在一个上下文环境中来确定。所以单独且隔离的来解释为什么是行不通的。在没有碰到相应的上下文时,先记下该语法,总会有用的时候。

    另,个人建议,在看书上示例时,不用一头扎进代码,先弄清楚,要解决的问题是什么。用什么样的解决方案。代码只不过是问题和解决方案的精确描述。

     

    2010年12月7日 2:47
    版主

全部回复

  • 第一个问题,代码中的 operator+,operator- 是分别对算术运算符 + 和 - 的重载决策。这样使得两个 Vector 实例可以利用 + 号进行矢量加运算,如 Vector v3 = v1 + v2;

    第二个问题,和 Main 方法在同一作用域的其他方法也只是静态方法定义而已,Program 本身是一个类型,类型上就可以放置如方法、静态域、属性等成员类型。Main 方法可以调用一个或多个这些方法,也可以不调用他们。


    Mark Zhou
    2010年12月3日 9:10
  • public double? ThetaRadians //这个ThetaRadians我没有办法取名字,根据它的返回值

      {        //return (Theta * Math.PI / 180)判断,是得到一个如果

       get      //继续乘以半径R就能得到扇形弧长的东东。。。???

       {

        return (Theta * Math.PI / 180);

       }

    上面的代码是一个属性声明:调用Get访问修饰符。

     public static Vector operator +(Vector op1, Vector op2)

      {

                  try//这段异常完全不懂,求详细补充???

                 {

                            double newX=op1 .R.Value*Math.Sin(op1.ThetaRadians.Value)

                                        +op2.R.Value *Math.Sin (op2.ThetaRadians .Value );

                            double newY = op1.R.Value * Math.Cos(op1.ThetaRadians.Value)

                                 + op2.R.Value * Math.Cos(op2.ThetaRadians.Value);
                       
                           double newR = Math.Sqrt(newX*newX+newY*newY );

                           double newTheta = Math.Atan2(newX, newY) * 180 / Math.PI;

                          return new Vector(newR, newTheta);

                }

                catch

                {

                        return new Vector(null,null);



                  }

      }

    上面的代码块用于重载“+”运算符。operator 关键字用于运算符重载功能

      try

    {

                catch

                {

                        
    return new Vector(null,null);



                  }

      }

    Try......Catch是一个代码块用于异常的捕获。

    如果Try代码块运行时出现异常,将由Catch代码块来捕获。

    在上面的代码中,如果:

                 try//这段异常完全不懂,求详细补充???

                 {

                           
    double newX=op1 .R.Value*Math.Sin(op1.ThetaRadians.Value)

                                        +op2.R.Value *Math.Sin (op2.ThetaRadians .Value );

                            
    double newY = op1.R.Value * Math.Cos(op1.ThetaRadians.Value)

                                 + op2.R.Value * Math.Cos(op2.ThetaRadians.Value);
                       
                          
    double newR = Math.Sqrt(newX*newX+newY*newY );

                           
    double newTheta = Math.Atan2(newX, newY) * 180 / Math.PI;

                         
    return new Vector(newR, newTheta);

                }


    这些代码运行出现异常,即异常会被Catch捕获,然后再返回 Vector 类的构造函数

    下面的两个方法同样是重载“-”运算符。

    public static Vector operator -(Vector op1)//不知道这段代码是干嘛用的???

      {

       return new Vector(-op1.R, op1.Theta);

      }

      public static Vector operator -(Vector op1, Vector op2)//不知道这段代码是干嘛用的???

      {

       return op1 + (-op2);

      }

    下面的这段代码是重写ToString方法。

     public override string ToString()//只知道是重写ToString,不明白重写的意义何在???

      {             //HasValue专门用于判断可空类型是否为空

       string rString = R.HasValue ? R.ToString() : "null";//非空则 rString= R.ToString()

       string thetaString = Theta.HasValue ? Theta.ToString() : "null";

       return string.Format("({0} , {1})",rString ,thetaString );

      }

    override 用于重写方法。

     

    static void Main(string[] args) 为静态方法入口点。

    public static Vector GetVector(string name) 和 public static double? GetNullableDouble()

    是用户自定义的方法,

    public static Vector GetVector(string name) 的返回类型为Vector类,name为GetVector函数的参数。

    public static double? GetNullableDouble()的返回类型为double。

     



     

     


    2010年12月3日 14:04
  • 谢谢大家!不过我感觉解释有些问题还停留在字面意思上!

        比如代码块几处都使用了 operator ,我想问为什么要用operator来重载运算符,而不是

    operator 是什么意思。

        还有try catch语句,我想问的是它的具体流程和每一行的解释,而不是笼统的 抛出异常、抓住异常

    之类的解释。

        总之,我想问的是为什么要这样做,而不是简单的翻译。菜鸟级别,希望大家谅解!

    2010年12月4日 13:41
  • dear
    1.operator定義如下
    使用 operator 关键字来重载内置运算符,或提供类或结构声明中的用户定义转换。
    http://msdn.microsoft.com/zh-cn/library/s53ehcz3(VS.90).aspx
    不知你有没有注意方法的写法,跟一搬的回传方法不一样

    2.每一个类别的例外都不一样,你可参考以下的说明
    http://www.dotblogs.com.tw/yc421206/archive/2009/07/17/9564.aspx

    3.ToString重写是为了要让方法转成字串时所要呈现的内容。
    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2010年12月4日 18:18
  • 对于运算符重载的问题,我想详细说一下。

    有一个简单的例子,您设计一个复数类 Complex,复数本身的数学运算包括加、减、乘、除、模等,但是,由于 Complex 的四则运算是非标准算术的四则元算,即,复数的四则运算是被复数本身这个类型自定义过的——例如,一个复数的加法操作应该是:

    Complex c1 + Complex c2 = (Complex) (c1.Real + c2.Real, c1.Imaginary + c2.Imaginary)

    所以,C# 必须一种方法,用来对标准的某一些运算符进行重载,这样,您就可以在自己的类型中使用它们,以增强代码阅读性。例如,Complex 上如果实现 + 重载,就可以利用 Complex c3 = c1 + c2 来直接执行加法,而不用运算符重载的话,必须声明一个 Add 方法然后这样使用:Complex c3 = c1.Add(c2); 这样的代码不够直观。

    在某些特定类型上的云算符重载可以帮助编译器提高生成代码的质量以及优化。比如,string 类型的 ==、!= 就是被重载过的。


    Mark Zhou
    2010年12月6日 9:33
  • 谢谢大家!不过我感觉解释有些问题还停留在字面意思上!

        比如代码块几处都使用了 operator ,我想问为什么要用operator来重载运算符,而不是

    operator 是什么意思。

        还有try catch语句,我想问的是它的具体流程和每一行的解释,而不是笼统的 抛出异常、抓住异常

    之类的解释。

        总之,我想问的是为什么要这样做,而不是简单的翻译。菜鸟级别,希望大家谅解!


    您好,想问为什么就需要弄清楚需求

    我们都知道1+1=2,可是你的项目需要1+1=1。怎么办?请用操作符重载。回到本例中,通常两个对象是不能直接相加的,正如mazhou解释的那样,为了Vector 实例能相加,达到Vector v3 = v1+v2的效果,才用操作符重载。如果您的需求是不需要两个Vector实例具有相加功能,可以不用操作符重载。这些是需求所决定的。

    try catch的含义是尽量来执行try里的代码块,如果有错误则捕获。如果需要自己来控制错误信息请用try catch,如果不需要控制错误信息,则不用

    编程里的很多语法功能,需要视您的需求而定。也就说需要在一个上下文环境中来确定。所以单独且隔离的来解释为什么是行不通的。在没有碰到相应的上下文时,先记下该语法,总会有用的时候。

    另,个人建议,在看书上示例时,不用一头扎进代码,先弄清楚,要解决的问题是什么。用什么样的解决方案。代码只不过是问题和解决方案的精确描述。

     

    2010年12月7日 2:47
    版主