首页 > 代码库 > 一起学习《C#高级编程》3--运算符重载

一起学习《C#高级编程》3--运算符重载

  运算符的重载。C++的开发人员应该很熟悉这个概念,但这对Java 和 VB 开发人员确实全新的。

  对于一些数值间的运算,如果通过方法来指定运算规则的话,不免会繁琐,这时就可以利用运算符的重载。

  例:

  Matrix a,b,c;  //定义矩阵对象

  Marix d=c*(a+b);

  如果用不支持运算符重载的语言的话,就必须定义方法,通过调用方法来进行计算:

  Marix d=c.Muliply(a.Add(b));

  结果很不直观

  

  运算符的重载,在数学或物理建模会经常用到(比如坐标,矢量,矩阵,函数运算等)。还有比如图形,财务方面。。当然,如果你要用于计算日期,比如两个DateTime相乘,没人会拦你,虽然在概念上没有任何意义,哈哈。

 

  其实,之前我们在编写代码的时候都会使用过运算符的重载,虽然我们自己没定义重载运算符,但C#默认有帮我们实现了。

int myInt=3;
uint myUint=2;
double myDouble=13.2;
long myLong=myInt+myUint;
double myDouble=myDouble+myInt;
double myDouble2=myInt+myDouble;

"+"运算符,会接受两个参数,然后根据参数查找最匹配的运算符的重载方法

上面的long myLong=myInt+myUint;和double myDouble2=myInt+myDouble;调用的是不同版本的重载。

在C#中,编译器会自动匹配最适合的重载方法,就如 对于double和int型数据,“+”运算符没有带这种复合参数的重载,所以编译器就认为,最匹配的“+”重载是两个double类型相加,所得到数是double类型也就不奇怪 了

 

那么对于自定义的类型会怎样呢,这样的话就得自己定义运算符的重载啦。

定义一个Vector结构,表示一个三维数学坐标 (x,y,z)

struct Vector
    {
        private double x, y, z;
        public Vector(double x,double y,double z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }
        public Vector(Vector vec)
        {
            this.x = vec.x;
            this.y = vec.y;
            this.z = vec.z;
        }
        
        public override string ToString()
        {
            return "(" + x + "," + y + "," + z + ")";
        }
        //+运算符重载
        public static Vector operator + (Vector lhs,Vector rhs)
        {
            Vector result=new Vector();
            result.x=lhs.x+rhs.x;
            result.y=lhs.y+rhs.y;
            result.z=lhs.z+rhs.z;

            return result;//返回两个3维坐标相加后的值
        }
    }
  

static void Main(string[] args)
{
//首先定义3维坐标对象
Vector vec1 = new Vector(1, 0, -2);
Vector vec2 = new Vector(2, -1, 5);
Vector vec3 = vec1 + vec2;


Console.WriteLine(vec1.ToString()); //输出(1,0,-2)
Console.WriteLine(vec2.ToString()); //输出(2,-1,5)
Console.WriteLine(vec3.ToString()); //输出(3,-1,3)
Console.ReadLine();
}


  当然还可以定义更多的重载运算,相加,相减,相乘。还可以标量与矢量相乘,比如 2*(1,2,3)

public static Vector operator *(double lhs,Vector rhs)
{
return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}

对于2.0*(1,2,3)和2*(1,2,3)都会调用这个重载。  但是,对于(1,2,3)*2,得另外重载一个方法

public static Vector operator *(Vector lhs,double rhs)
{
return rhs * lhs;
}

这里,没必要像上一个方法那样重新运算过程,直接重用上面的代码。。这个阐述了代码的简洁思想,也提高了代码的可维护性。

相信,接下来写矢量相乘的话,也不是难事了,就不多写了。

 

当然,还有就是比较符的重载,包括下面3对:

==和!=

>和<

>=和<=

其实,重载方法的操作是一样的,把上例重点"+"运算符改为 比较运算符。

public static bool operator ==(Vector lhs,Vector rhs)
{
return ???
}

 

竟然写了一个小时,0:11了,赶紧睡觉!

下期内容: 常见的系统预制数值类型的转换(比如 float转换成double),那用户定义的类型的转换又是怎样的呢?

下期叙述, 用户定义类型的强制转换

参考页面:

http://www.yuanjiaocheng.net/CSharp/Csharp-fileinfo.html

http://www.yuanjiaocheng.net/mvc/mvc-models.html

http://www.yuanjiaocheng.net/entity/delete-entity.html

http://www.yuanjiaocheng.net/Jsp/first.html

http://www.yuanjiaocheng.net/ASPNET-CORE/attribute-route.html

http://www.yuanjiaocheng.net/CSharp/Csharp-while-loop.html

http://www.yuanjiaocheng.net/CSharp/csharp-Predicate-delegate.html

http://www.yuanjiaocheng.net/ASPNET-CORE/core-configuration.html

http://www.yuanjiaocheng.net/Linq/linq-lambda-expression.html

http://www.yuanjiaocheng.net/Java/internal-details-of-hello-java-program.html

http://www.yuanjiaocheng.net/ASPNET-CORE/core-identity-migrations.html

一起学习《C#高级编程》3--运算符重载