服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#中explicit与implicit的深入理解

C#中explicit与implicit的深入理解

2022-07-22 10:14依乐祝 C#

这篇文章主要给大家介绍了关于C#中explicit与implicit的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

今天在研究公司项目框架的时候看到了下面的用法,public static implicit operator JsonData(int data); 。貌似很久没用过这种隐式转换的写法了,因此重新温习一下C#中转换相关的知识。

explicit 和 implicit 属于转换运算符,如用这两者可以让我们自定义的类型支持相互交换

explicti 表示显式转换,如从 A -> B 必须进行强制类型转换(B = (B)A)

implicit 表示隐式转换,如从 B -> A 只需直接赋值(A = B)

implicit

implicit 关键字用于声明隐式的用户自定义的类型转换运算符。 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。

使用隐式转换操作符之后,在编译时会跳过异常检查,所以隐式转换运算符应当从不引发异常并且从不丢失信息,否则在运行时会出现一些意想不到的问题。

示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Digit
{
 public Digit(double d) { val = d; }
 public double val;
 // ...other members
 
 // User-defined conversion from Digit to double
 public static implicit operator double(Digit d)
 {
  return d.val;
 }
 // User-defined conversion from double to Digit
 public static implicit operator Digit(double d)
 {
  return new Digit(d);
 }
}
 
class Program
{
 static void Main(string[] args)
 {
  Digit dig = new Digit(7);
  //This call invokes the implicit "double" operator
  double num = dig;
  //This call invokes the implicit "Digit" operator
  Digit dig2 = 12;
  Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val);
  Console.ReadLine();
 }
}

隐式转换可以通过消除不必要的强制转换来提高源代码的可读性。 但是,因为隐式转换不需要程序员将一种类型显式强制转换为另一种类型,所以使用隐式转换时必须格外小心,以免出现意外结果。 一般情况下,隐式转换运算符应当从不引发异常并且从不丢失信息,以便可以在程序员不知晓的情况下安全使用它们。 如果转换运算符不能满足那些条件,则应将其标记为 explicit。 有关详细信息,请参阅使用转换运算符

explicit显示转换

explicit 关键字声明必须通过显示的调用用户定义的类型转换运算符来进行转换。

以下示例定义从 Fahrenheit 类转换为 Celsius 类的运算符。 必须在 Fahrenheit 类或 Celsius 类中定义运算符:

?
1
2
3
4
public static explicit operator Celsius(Fahrenheit fahr)
{
 return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
}

如下所示,调用用户定义的转换运算符来强制转换:

?
1
2
3
Fahrenheit fahr = new Fahrenheit(100.0f);
Console.Write($"{fahr.Degrees} Fahrenheit");
Celsius c = (Celsius)fahr;

此转换运算符从源类型转换为目标类型。 源类型提供转换运算符。 不同于隐式转换,显式转换运算符必须通过转换的方式来调用。 如果转换操作会导致异常或丢失信息,则应将其标记为 explicit。 这可阻止编译器静默调用可能产生意外后果的转换操作。

省略转换将导致编译时错误 CS0266。

有关详细信息,请参阅使用转换运算符

示例

下面的示例提供了 Fahrenheit 和 Celsius 类,其中每个类均提供转换为其他类的显式转换运算符。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Celsius
{
 public Celsius(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Fahrenheit(Celsius c)
 {
  return new Fahrenheit((9.0f / 5.0f) * c.Degrees + 32);
 }
}
 
class Fahrenheit
{
 public Fahrenheit(float temp)
 {
  Degrees = temp;
 }
 
 public float Degrees { get; }
 
 public static explicit operator Celsius(Fahrenheit fahr)
 {
  return new Celsius((5.0f / 9.0f) * (fahr.Degrees - 32));
 }
}
 
class MainClass
{
 static void Main()
 {
  Fahrenheit fahr = new Fahrenheit(100.0f);
  Console.Write($"{fahr.Degrees} Fahrenheit");
  Celsius c = (Celsius)fahr;
 
  Console.Write($" = {c.Degrees} Celsius");
  Fahrenheit fahr2 = (Fahrenheit)c;
  Console.WriteLine($" = {fahr2.Degrees} Fahrenheit");
 }
}
// 输出:
// 100 Fahrenheit = 37.77778 Celsius = 100 Fahrenheit

示例

下面的示例定义结构 Digit,它表示单个的十进制数字。 将运算符定义为从 byte 到 Digit 的转换,但由于并非所有字节都可转换为 Digit,因此该转换应该应用显式转换。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
struct Digit
{
 byte value;
 public Digit(byte value)
 {
  if (value > 9)
  {
   throw new ArgumentException();
  }
  this.value = value;
 }
 
 // 定义从byte到Digit的显示转换 explicit operator:
 public static explicit operator Digit(byte b)
 {
  Digit d = new Digit(b);
  Console.WriteLine("转换已完成");
  return d;
 }
}
 
class ExplicitTest
{
 static void Main()
 {
  try
  {
   byte b = 3;
   Digit d = (Digit)b; // 显示转换
  }
  catch (Exception e)
  {
   Console.WriteLine("{0} 捕获到一成.", e);
  }
 }
}
/*
输出:
转换已完成
*/

参考资料

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对服务器之家的支持。

原文链接:http://www.cnblogs.com/yilezhu/p/10898582.html

延伸 · 阅读

精彩推荐
  • C#C#将图片存放到SQL SERVER数据库中的方法

    C#将图片存放到SQL SERVER数据库中的方法

    这篇文章主要介绍了C#将图片存放到SQL SERVER数据库中的方法,以实例形式较为详细的分析了C#保存图片到SQL Server数据库的具体步骤与相关技巧,具有一定参考...

    我心依旧11262021-10-27
  • C#C#中使用JSON.NET实现JSON、XML相互转换

    C#中使用JSON.NET实现JSON、XML相互转换

    这篇文章主要介绍了C#中使用JSON.NET实现JSON、XML相互转换的相关代码及示例,需要的朋友可以参考下...

    C#教程网4282021-11-03
  • C#详解C#开发Android应用程序的流程

    详解C#开发Android应用程序的流程

    在本篇文章里小编给大家分享了关于C#开发Android应用程序的流程和相关技巧,需要的朋友们跟着学习下。...

    C#教程网4612022-07-16
  • C#Unity3D Shader实现贴图切换效果

    Unity3D Shader实现贴图切换效果

    这篇文章主要为大家详细介绍了Unity3D Shader实现贴图切换效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    星空不语8442022-07-08
  • C#C#自定义事件监听实现方法

    C#自定义事件监听实现方法

    这篇文章主要介绍了C#自定义事件监听实现方法,涉及C#事件监听的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    我心依旧11592021-10-21
  • C#C# 将字节流转换为图片的实例方法

    C# 将字节流转换为图片的实例方法

    C# 将字节流转换为图片的实例方法,需要的朋友可以参考一下...

    C#教程网1742020-12-18
  • C#C#实现餐饮管理系统

    C#实现餐饮管理系统

    这篇文章主要为大家详细介绍了C#实现餐饮管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    wxtydd1234362022-03-09
  • C#输出的文本实现对齐的方法(超简单)

    输出的文本实现对齐的方法(超简单)

    下面小编就为大家分享一篇c#输出的文本实现对齐的方法,特别简单!希望对大家有所帮助。一起跟随小编过来看看吧...

    杨明波(Leo Yang)10902022-02-15