在C#当中我们可以看到 两个DateTime是可以直接用-来相减的。定义-
这个行为就叫做运算符重载
下面的这个例子是我在很早以前以为模仿 股票数据而写的一个类。
public class FloatList : List<float>
{
public FloatList()
{ }
public FloatList(IEnumerable<float> input)
: base(input)
{ }
public FloatList(params float[] input)
: base(input)
{ }
//定义了 floatList可以直接加上一个float
public static FloatList operator +(FloatList input, float m)
{
FloatList list = new FloatList();
for (int i = 0; i < input.Count; i++)
{
list.Add(input[i] + m);
}
return list;
}
//定义了 floatList可以直接减去一个数
public static FloatList operator -(FloatList input, float m)
{
FloatList list = new FloatList();
for (int i = 0; i < input.Count; i++)
{
list.Add(input[i] - m);
}
return list;
}
//...
}
class Program
{
static void Main(string[] args)
{
var list = new FloatList(1, 2, 3);
var k = list + 5;
// list+=5; // 重载了 + 号 就自动有了 +=
// k就是 6 7 8了
}
}
示例2 重载 一元运算符的 -
public class FloatList : List<float>
{
public FloatList(int a)
{ }
public FloatList(IEnumerable<float> input)
: base(input)
{ }
public FloatList(params float[] input)
: base(input)
{ }
public static FloatList operator -(FloatList input)
{
FloatList list = new FloatList();
for (int i = 0; i < input.Count; i++)
{
list.Add(-input[i]);
}
return list;
}
}
class Program
{
static void Main(string[] args)
{
var my = new FloatList(2, -3, 4);
var k = -my;
// k 为 -2 3 -4
}
}
下表描述了 C# 中运算符重载的能力:
运算符 | 描述 |
---|---|
+x、-x、!x、~x、++、--、true、false | 这些一元运算符可以进行重载。 |
x + y、x - y、x * y、x / y、x % y、x & y、x | y、x ^ y、x << y, x >> y、x == y、x != y、x < y, x > y、x <= y, x >= y | 这些二元运算符可以进行重载。 某些运算符必须成对重载;有关详细信息,请查看此表后面的备注。 |
x && y、x || y | 无法重载条件逻辑运算符。 但是,如果具有已重载的 true 和 false 运算符的类型还以某种方式重载了 & 或 | 运算符,则可针对此类型的操作数分别计算 && 或 || 运算符。 有关详细信息,请参阅 C# 语言规范的用户定义条件逻辑运算符部分。 |
a[i], a?[i] | 元素访问不被视为可重载运算符,但你可定义索引器。 |
(T)x | 强制转换运算符不能重载,但可以定义可由强制转换表达式执行的自定义类型转换。 有关详细信息,请参阅用户定义转换运算符。 |
+=、-=、*=、/=、%=、&=、|=、^=、<<=, >>= | 复合赋值运算符不能显式重载。 但在重载二元运算符时,也会隐式重载相应的复合赋值运算符(若有)。 例如,使用 +(可以进行重载)计算 +=。 |
^x、x = y、x.y、x?.y、c ? t : f、x ?? y、x ??= y、x..y、x->y、=>、f(x)、as、await、checked、unchecked、default、delegate、is、nameof、new、sizeof、stackalloc、switch、typeof、with | 这些运算符无法进行重载。 |
C# 要求成对重载比较运算符。如果重载了==,则也必须重载!=,否则产生编译错误。同时,比较运算符必须返回bool类型的值,这是与其他算术运算符的根本区别。
C# 不允许重载=运算符,但如果重载例如+运算符,编译器会自动使用+运算符的重载来执行+=运算符的操作。
运算符重载的其实就是函数重载。首先通过指定的运算表达式调用对应的运算符函数,然后再将运算对象转化为运算符函数的实参,接着根据实参的类型来确定需要调用的函数的重载,这个过程是由编译器完成。
public class Student
{
public string Name { get; set; }
public static implicit operator Student(string value)
{
return new Student()
{
Name = value
};
}
}
class Program
{
static void Main(string[] args)
{
Student s = "malema.net"; //不需要用new就可以创建实例了 隐式转换了
Console.WriteLine(s.Name); //malema.net
}
}
public class Teacher
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Student s = "malema.net"; //不需要用new就可以创建实例了.
Console.WriteLine(s.Name); //malema.net
}
}
class Program
{
static void Main(string[] args)
{
var teacher = new Teacher() { Name = "malema.net" };
Student s = (Student)teacher;
Console.WriteLine(s.Name);//malema.net
}
}