当前位置: 首页 > 编程笔记 >

实例分享C#中Explicit和Implicit用法

章岳
2023-03-14
本文向大家介绍实例分享C#中Explicit和Implicit用法,包括了实例分享C#中Explicit和Implicit用法的使用技巧和注意事项,需要的朋友参考一下

今天在Review一个老项目的时候,看到一段奇怪的代码。

if (dto.Payment == null) continue;
var entity = entries.FirstOrDefault(e => e.LedgerEntryID == dto.LedgerEntryID);
dto.Payment = entity?.Payment;

其中dto.Payment是一个PaymentDTO类的实例,entity?.Payment是一个Payment类的实例,PaymentDTO类和Payment类没有子父关系,所以不存在子类和父类之间的隐式转换。

奇怪的是Visual Studio的编译器没有提示任何编译错误。

打开PaymentDTO类的定义之后,发现了以下方法签名。

public static implicit operator PaymentDTO(Payment payment)

从方法签名上看,这就是重写PaymentDTO类型的操作符,但并不是我以前常用的+,-,*,/, ==等。

查询MSDN之后,才了解到implicit和explicit是一对转换操作符。

Implicit和Explicit

Implicit

Implicit关键字用于声明隐式的用户定义类型转换运算符。它可以实现2个不同类的隐式转换 ,提高代码的可读性。但是需要注意使用隐式转换操作符之后,在编译时会跳过异常检查,所以隐式转换运算符应当从不引发异常并且从不丢失信息,否则在运行时会出现一些意想不到的问题。

例如当前PaymentDTO和Payment的定义如下

public class Payment
  {
     public decimal Amount { get; set; }
  }
  public class PaymentDTO
  {
     public string AmountString { get; set; }
  }

如果需要将Payment隐式转换成PaymentDTO, 仅需声明PaymentDTO的隐式转换运算符

public class PaymentDTO
    {
      public string AmountString { get; set; }
public static implicit operator PaymentDTO(Payment payment)
      {
        return new PaymentDTO
        {
AmountString = payment.Amount.ToString("C2")
        };
      }
    }

调用时只需要直接赋值就可以

class Program
    {
      static void Main(string[] args)
      {
PaymentDTO dto = new Payment { Amount = 1 };
        Console.WriteLine(dto.AmountString);
        Console.Read();
      }
    }

Explicit

Explicit关键字声明必须通过转换来调用的用户定义的类型转换运算符。不同于隐式转换,显式转换运算符必须通过转换的方式来调用,如果缺少了显式的转换,在编译时就会产生错误。

例如现在我们将前面PaymentDTO类中定义的转换操作符从Implicit变为Explicit

public class PaymentDTO
    {
      public string AmountString { get; set; }
public static explicit operator PaymentDTO(Payment payment)
      {
        return new PaymentDTO
        {
AmountString = payment.Amount.ToString("C2")
        };
      }
    }

这时候由于Main方法中没有显式转换,所以编译器出错,提示Cannot implicitly convert type 'ExplicitImplicit.Payment' to 'ExplicitImplicit.PaymentDTO'. An explicit conversion exists (are you missing a cast?)

如果想要编译器通过编译, 只需要做一个显示转换即可

class Program
    {
      static void Main(string[] args)
      {
PaymentDTO dto = (PaymentDTO)new Payment { Amount = 1 };
        Console.WriteLine(dto.AmountString);
        Console.Read();
      }
    }

总结

Implicit提高了代码的可读性,但程序员需要自己保证转换不引发异常且不丢失信息

Explicit可阻止编译器静默调用可能产生意外后果的转换操作。

前者更易于使用,后者能向阅读代码的每个人清楚地指示您要转换类型

以上就是我们给大家整理的C#中Explicit和Implicit用法的全部内容,大家在学习的时候可以多多参考实例,感谢你对小牛知识库的支持。

 类似资料:
  • 本文向大家介绍C++ explicit构造函数实例解析,包括了C++ explicit构造函数实例解析的使用技巧和注意事项,需要的朋友参考一下 按照C语言默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: 但是有的时候可能会不需要这种隐式转换,如下: 下面两种写法比较正常: 下面两种写法就比较疑惑了: s4 和s5 分别把一个int型和

  • 本文向大家介绍C#中is和as用法实例分析,包括了C#中is和as用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#中is和as的用法,对加深is与as用法的理解有一定的帮助借鉴作用。具体如下: 现来看个例子: 这样会报错(InvalidCastException),由于C#安全机制,它会去判断一次。我们这里做了非法的转换。 Is做判断:is说判断对象是不是你要的那个类型(这

  • 本文向大家介绍C语言时间处理实例分享,包括了C语言时间处理实例分享的使用技巧和注意事项,需要的朋友参考一下 一、简介 时间处理在编程中经常遇到,包括程序的运行时间和显示时间等。在标准C中, 日期和时间的处理包含在 time.h 的头文件中,需要使用日期和时间相关的类型的函数的话, 需要导入time.h. 二、实例 1、计算时差 编译 gcc  -g -o time_diff time_diff.c

  • 本文向大家介绍C++中stringstream的用法和实例,包括了C++中stringstream的用法和实例的使用技巧和注意事项,需要的朋友参考一下 之前在leetcode中进行string和int的转化时使用过istringstream,现在大致总结一下用法和测试用例。 介绍:C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对

  • 本文向大家介绍php算法实例分享,包括了php算法实例分享的使用技巧和注意事项,需要的朋友参考一下 只打印0   具体个数由输入的参数n决定   如n=5就打印00000 打印一行 0101010101010101010101   具体个数由输入的参数n决定   如test.php?n=3打印010 实现1 00 111 0000 11111   for if 实现   for switch 实现

  • 本文向大家介绍C#中this的使用实例分析,包括了C#中this的使用实例分析的使用技巧和注意事项,需要的朋友参考一下 this关键字在C#程序设计中的应用非常频繁,今天本文就this关键字的用法做一番分析,希望能提对大家的C#程序设计有一定的帮助作用。具体分析如下: 1.代表当前类,在当前类中可使用this访问当前类成员变量和方法(需要注意的是 静态方法中不能使用this),也可用于参数传递,传