6 用户定义类型转换 运算符重载 typeof运算符

用户定义类型转换

c# 提供隐示转换 和 显示转换

  • 对于隐示转换,当决定在特定上下文中使用特定的类型时,如果有必要,编译器会自动执行转换
  • 对于显示转换,编译器只在使用显示转换运算符时才执行转换

声明隐示转换语法如下。publicstatic 修饰符是所有用户自定义的转换所必须的

// 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);
posted @ 2022-10-29 00:06  LD_Dragon_sky  阅读(22)  评论(0编辑  收藏  举报