6 用户定义类型转换 运算符重载 typeof运算符
用户定义类型转换
c# 提供隐示转换 和 显示转换
- 对于隐示转换,当决定在特定上下文中使用特定的类型时,如果有必要,编译器会自动执行转换
- 对于显示转换,编译器只在使用显示转换运算符时才执行转换
声明隐示转换语法如下。public 和 static 修饰符是所有用户自定义的转换所必须的
// public static 必须的 目标类型 数据源
public static implicit operator TargetType(sourceType data);
显示转换的语法与之相同,需要用 explicit 替换掉 implicit
下面代码展示声明转换运算符的示例,他把类型LimitedInt 的对象 转换为 int 型,反之亦然
隐示转换
class LimitedInt
{
private int _value = 0;
public int Value {
get { return _value; }
set { this._value = value; }
}
// 将 LimitedInt转换为int
public static implicit operator int(LimitedInt li)
{
return li.Value;
}
// 将int转换成LimitedInt
public static implicit operator LimitedInt(int x)
{
LimitedInt li = new LimitedInt();
li.Value = x;
return li;
}
}
转换
static void Main(string[] args)
{
LimitedInt limitedInt = new LimitedInt();
int res = limitedInt;
res = 15;
limitedInt = res;
Console.WriteLine(limitedInt);
Console.ReadKey();
}
显示转换
// 显示转换
class LimitedInt2
{
private int _value = 0;
public int Value
{
get { return _value; }
set { this._value = value; }
}
// 将 LimitedInt转换为int
public static explicit operator int(LimitedInt2 li)
{
return li.Value;
}
// 将int转换成LimitedInt
public static explicit operator LimitedInt2(int x)
{
LimitedInt2 li = new LimitedInt2();
li.Value = x;
return li;
}
}
LimitedInt2 limitedInt2 = new LimitedInt2();
int res2 = (int)limitedInt2;
res2 = 15;
limitedInt2 = (LimitedInt2)res2;
Console.WriteLine(limitedInt2.Value);
Console.ReadKey();
另外有两个运行符,接受一种类型的值,并返回另一种不同的,指定类型的值。这就是is运算符合as运算符,我们在后面介绍他
运算符重载
- 运算符重载只能用于类和结构。
- 为类或结构重载一个运算符x,可以声明一个名称为operator x的方法并实现他的行为(例如:operator + 或 operator -)
- 一元运算符的重载方法带一个单独的class或struct类型的参数。
- 二元运算符的重载方法带两个参数,其中至少有一个必须是class或struct类型。
public static LimitedInt operator - (LimitedInt x);
public static LimitedInt operator + (LimitedInt x,double y);
运算符的方法声明:
- 声明必须同时使用static 和 public 的修饰符;
- 运算符必须是要操作的类或结构的成员。
class LimitedInt3
{
public double value = 0;
// 二元运算符
public static LimitedInt3 operator +(LimitedInt3 x, double y)
{
LimitedInt3 li = new LimitedInt3();
li.value = x.value + y;
return li;
}
// 一元运算符
public static LimitedInt3 operator - (LimitedInt3 x)
{
LimitedInt3 li = new LimitedInt3();
li.value = -(x.value);
return li;
}
}
使用
LimitedInt3 l3 = new LimitedInt3();
l3.value = 15;
LimitedInt3 l4 = l3 + 10;
Console.WriteLine(l4.value);
l4 = -l4;
Console.WriteLine(l4.value);
Console.ReadKey();
运算符重载的限制
不是所有运算符都能被重载,可以重载的列席也有限制
只有下面这些运算符可以被重载。列表中明显缺少的是赋值运算符
- 可重载的一元运算符: + - ! ~ ++ -- true false
- 可重载的二元运算符:+ - * / % & | ^ << >> == != >< >= <=
Typeof 运算符
typeof运算符返回作为其参数的任何类型的System.Type对象。 通过这个对象,可以了解类型的特征。(对任何已知类型,只有一个System.Type对象) 不能重载typeof运算符。
运算符 | 描述 |
---|---|
typeof | 返回已知类型的System.Type对象 |
下面是typeof运算符语法的示例,Type是System命名空间中的一个类
Type t = typeof(SomeClass)
下面利用typeof运算符获取SomeClass类的信息,并打印出他的公有字段和方法
using System.Reflection; // 使用反射命名空间来全面利用检测类型信息的功能
Type t = typeof(LimitedInt);
FieldInfo[] fi = t.GetFields();
MethodInfo[] mi = t.GetMethods();
foreach (var item in fi)
{
Console.WriteLine("Field : {0}" ,item.Name);
}
foreach (var item in mi)
{
Console.WriteLine("Method : {0}", item.Name);
}
Console.ReadKey();
结果:
Field : _value
Method : get_Value
Method : set_Value
Method : op_Implicit
Method : op_Implicit
Method : Equals
Method : GetHashCode
Method : GetType
Method : ToString
GetType方法也会调用typeof运算符,该方法对每个类型的每个对象都有效
Console.WriteLine("Type s:{0}",limitedInt.GetType().Name);
吾虽浪迹,却未迷失本心