zoukankan      html  css  js  c++  java
  • C#中转换运算符explicit、implicit、operator、volatile研究

    C#中的这个几个关键字:explicit、implicit与operator,估计好多人的用不上,什么情况,这是什么?字面解释:explicit:清楚明白的;易于理解的;(说话)清晰的,明确的;直言的;坦率的;直截了当的;不隐晦的;不含糊的。implicit:含蓄的;不直接言明的;成为一部分的;内含的;完全的;无疑问的。operator:操作人员;技工;电话员;接线员;(某企业的)经营者,专业公司。说了这么多,其实explicit和implicit关键字分别表示显式的类型转换和隐式的类型转换。

    volatile 关键字指示一个字段可以由多个同时执行的线程修改,可以保证值得最新。编译器在优化代码时,可能会把经常用到的代码存在Cache里面,然后下一次调用就直接读取Cache而不是内存,这样就大大提高了效率。但是问题也随之而来了,在多线程程序中,如果把一个变量放入Cache后,又有其他线程改变了变量的值,那么本线程是无法知道这个变化的。它可能会直接读Cache里的数据,但是很不幸,Cache里的数据已经过期了,读出来的是不合时宜的脏数据,这时就会出现bug。用volatile 声明变量可以很好的解决这个问题。

    显式转换

    显式转换(强制转换):必须使用强制运算符,才能执行的转换,在转换过程中可能会丢失信息或转换失败。
    例如

    public class BaseAB { }
    public class A : BaseAB { }
    public class B : BaseAB { }
    //测试
    double test = 1.234;
    int testInt = (int)test;
    Console.WriteLine(testInt); //运算结果1,强制转换数据丢失
    
    try {
        BaseAB ab = new A();
        B b = (B)ab;  //引用强制转换抛出异常 System.InvalidCastException: Unable to cast object of type 'A' to type 'B'.
    } catch (Exception ex) {
        Console.WriteLine(ex.ToString());
    }

    在值类型强制转换的时候,会数据丢失,在引用类型做强制转换的时候会有引发InvalidCastException风险,但是可以通过使用模式匹配安全的进行强制转换,通过is和as运算符来检测是否属于特定类型。
    模式匹配:给定一个子串,要求在某个字符串中找出与该子串相同的所有子串。例如:A是字串,BA是待查找的字符串,要求从BA中查找出所有与A相同的字串,这个问题就是模式匹配问题。A是模式,BA是目标。
    例如:

    var test = 1.1234;
    int testInt = test is int ? (int)test : 0;
    Console.WriteLine(testInt);
    BaseAB ab = new A();
    B b = ab as B;
    if (b == null) Console.WriteLine("ab 不是 B类型");
    //结果:
    //0
    //ab 不是 B类型
    

    隐式转换

    隐式转换:这种转换是类型安全的,不需要特殊处理。
    例如:

    int i = 123;
    double b = i;
    Console.WriteLine(b);
    
    A a = new A();
    BaseAB baseAB = a;
    //结果:
    //123

    简单来说就是:小类型转换成大类型的时候隐式转换,大类型转换成小类型用强制转换。int > float > double >deca

    正题

    operator 关键字用于在类或结构声明中声明运算符。运算符声明可以采用下列四种形式之一:

    public static result-type operator unary-operator (type1 param)
    public static result-type operator binary-operator (type1 param1, type2 param)
    public static implicit operator result-type (type param )
    public static explicit operator result-type (type param )

    参数说明:
    result-type:结果类型
    type,type1,type2:参数类型
    unary-operator: + - ! ~ ++ — true false
    binary-operator: + - * / % & | ^ << >> == != > < >= <=

    介绍了这么多,开始步入正题,讲解explicit、implicit与operator。explicit、implicit都是与operator一起操作使用的,operator 关键字用于在类或结构声明中声明运算符。explicit用于强制转换,implicit用于隐式转换。
    例如:

    public struct MeDecimal
    {
        private readonly int intV;
        private readonly double doubleV;
    
        public MeDecimal(int value):this(value,0)
        {
        }
    
        public MeDecimal(double value):this(0,value)
        {
        }
    
        public MeDecimal(int intV, double doubleV)
        {
            this.intV = intV;
            this.doubleV = doubleV;
        }
    
        public static implicit operator int(MeDecimal meDecimal)
        {
            return meDecimal.intV;
        }
    
        public static explicit operator double(MeDecimal meDecimal)
        {
            return meDecimal.doubleV;
        }
    
        public static implicit operator MeDecimal(int meDecimal)
        {
            return new MeDecimal(meDecimal);
        }
    
        public static explicit operator MeDecimal(double meDecimal)
        {
            return new MeDecimal(meDecimal);
        }
    
        public static MeDecimal operator ++(MeDecimal meDecimal)
        {
            var t = meDecimal.intV + 1;
            var t2 = meDecimal.doubleV + 1;
            var temp = new MeDecimal(t, t2);
            return temp;
        }
    
        public override string ToString()
        {
            return $"intV:{intV},doubleV:{doubleV}";
        }
    }

    用法:

    MeDecimal d = (MeDecimal)2.1;
    Console.WriteLine($"原始数据:{d}");
    d++;
    double c = (double)d;
    int c2 = d;
    Console.WriteLine($"int的值:{c2},double的值:{c}");
    Console.WriteLine($"{d}");

    //结果:
    原始数据:intV:0,doubleV:2.1
    int的值:1,double的值:3.1
    intV:1,doubleV:3.1

    像一些类型需要转换的地方或者特殊处理的地方,可以用explicit、implicit,方便操作。

  • 相关阅读:
    gdb简易教程
    使用WoeUSB在Linux上制作Win10启动盘
    How to fix git: new blank line at EOF
    使用CSS3动画属性实现各种旋转跳跃
    jQuery事件
    挖矿程序minerd入侵分析和解决办法
    css3的伪(伪类和伪元素)大合集
    HTML 5 <blockquote><p>的分工与合作
    HTML<figure> <figcaption> 标签定义图文并茂
    监听 返回按钮事件
  • 原文地址:https://www.cnblogs.com/zhao123/p/11120523.html
Copyright © 2011-2022 走看看