explicit和implicit

来源:互联网 发布:雅思阅读知乎 编辑:程序博客网 时间:2024/05/20 23:30

explicit

explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符。

static explicit operator target_type { source_type identifier }

参数

  1. target_type 目标类型
  2. source_type 源类型。
  3. identifier Something。

注意

  1. 转换运算符将源类型转换为目标类型。源类型提供转换运算符。与隐式转换不同,必须通过强制转换的方式来调用显式转换运算符。如果转换操作可能导致异常或丢失信息,则应将其标记为 explicit。这可以防止编译器无提示地调用可能产生无法预见后果的转换操作。

implicit

implicit 关键字用于声明隐式的用户定义类型转换运算符。

static implicit operator target_type { source_type identifier }
注意
  1. 隐式转换可以通过消除不必要的类型转换来提高源代码的可读性。但是,因为可以在程序员未指定的情况下发生隐式转换,因此必须注意防止令人不愉快的后果。一般情况下,隐式转换运算符应当从不引发异常并且从不丢失信息,以便可以在程序员不知晓的情况下安全使用它们。如果转换运算符不能满足那些条件,则应将其标记为 explicit。

示例

以下是一个综合示例,简要展示用法。如要更具体细节的了解,请参阅MSDN Library。

namespace Hunts.Keywords
{
    
// 定义一个人民币结构。数据类型转换的语法对于结构和类是一样的
    public struct RMB
    
{
        
// 注意:这些数的范围可能不能满足实际中的使用
        public uint Yuan;
        
public uint Jiao;
        
public uint Fen;

        
public RMB(uint yuan, uint jiao, uint fen)
        
{
            
if (fen > 9)
            
{
                jiao 
+= fen / 10;
                fen 
= fen % 10;
            }

            
if (jiao > 9)
            
{
                yuan 
+= jiao / 10;
                jiao 
= jiao % 10;
            }

            
this.Yuan = yuan;
            
this.Jiao = jiao;
            
this.Fen = fen;
        }


        
public override string ToString()
        
{
            
return string.Format("¥{0}元{1}角{2}分", Yuan, Jiao, Fen);
        }


        
// 一些操作
        public static RMB operator +(RMB rmb1, RMB rmb2)
        
{
            
return new RMB(rmb1.Yuan + rmb2.Yuan, rmb1.Jiao + rmb2.Jiao, rmb1.Fen + rmb2.Fen);
        }


        
public static implicit operator float(RMB rmb)
        
{
            
return rmb.Yuan + (rmb.Jiao/10.0f+ (rmb.Fen/100.00f);
        }


        
public static explicit operator RMB(float f)
        
{
            
uint yuan = (uint)f;
            
uint jiao = (uint)((f - yuan) * 10);
            
uint fen = (uint)(((f - yuan) * 100% 10);
            
return new RMB(yuan, jiao, fen);
        }


        
// more
    }

    
class App
    
{
        
static void Main()
        
{
            RMB r1, r2, r3, r4;

            
// 记得小学时的某次捐款,我把口袋里藏好的一块钱加6张一毛钱以及13个一分钱的硬币都贡献出去了:(
            r1 = new RMB(1613);
            
// 其实当时其他人都已经交过了,他们总共交了:
            r2 = new RMB(4693);
            
// 那么加上我的就是:
            r3 = r1 + r2;
            Console.WriteLine(
"r3 = {0}", r3.ToString());

            
// 隐式转换
            float f = r3;
            Console.WriteLine(
"float f= {0}", f);

            
// 显式转换
            r4 = (RMB)f;
            Console.WriteLine(
"r4 = {0}", r4.ToString());
            
//如果不进行显示转换,将出现错误 CS0266: 无法将类型“float”隐式转换为“Hunts.Keywords.RMB”。存在一个显式转换(是否缺少强制转换?)

            Console.Read();
        }

    }

}
/*
控制台输出:
r3 = ¥48元6角6分
float f = 48.66
r4 = ¥48元6角5分
*/

我们会发现r4结果少了一分钱!这是因为在:

uint fen = (uint)(((f - yuan) * 100% 10);

这句中,在将float转换为uint时发生了圆整错误(这与计算机以二进制存储有关)。解决这个错误,我们可以使用System.Convert类中用于处理数字的静态方法:

uint fen = Convert.ToUInt32(((f - yuan) * 100% 10);

不过使用System.Convert处理会有些性能的损失。


原创粉丝点击