gpt4 book ai didi

c# - 为什么 C# 编译器不调用隐式转换运算符?

转载 作者:太空狗 更新时间:2023-10-29 20:51:08 25 4
gpt4 key购买 nike

假设我们有以下类型:

struct MyNullable<T> where T : struct
{
T Value;

public bool HasValue;

public MyNullable(T value)
{
this.Value = value;
this.HasValue = true;
}

public static implicit operator T(MyNullable<T> value)
{
return value.HasValue ? value.Value : default(T);
}
}

并尝试编译以下代码片段:

MyNullable<int> i1 = new MyNullable<int>(1);
MyNullable<int> i2 = new MyNullable<int>(2);

int i = i1 + i2;

这个片段编译得很好,没有错误。 i1 和 i2 转换为整数并计算加法。

但是如果我们有以下类型:

struct Money
{
double Amount;
CurrencyCodes Currency; /*enum CurrencyCode { ... } */

public Money(double amount, CurrencyCodes currency)
{
Amount = amount;
Currency = currency;
}

public static Money operator + (Money x, Money y)
{
if (x.Currency != y.Currency)
// Suppose we implemented method ConvertTo
y = y.ConvertTo(x.Currency);

return new Money(x.Amount + y.Amount, x.Currency);
}
}

尝试编译另一个代码片段:

MyNullable<Money> m1 = 
new MyNullable<Money>(new Money(10, CurrenciesCode.USD));
MyNullable<Money> m2 =
new MyNullable<Money>(new Money(20, CurrenciesCode.USD));

Money m3 = m1 + m2;

现在的问题是,为什么编译器会生成“错误 CS0019:运算符‘+’无法应用于‘MyNullable ’和‘MyNullable ’类型的操作数 ”? p>

最佳答案

这是个有趣的问题……它适用于 Decimal ,例如,但不是 TimeSpan ,它们都是正确的 .NET 类型(不像 float 等是原始类型)并且都有一个 + 运算符。好奇!

当然,您可以通过以下方式扭转 ARM :

Money m3 = (Money)m1 + (Money)m2;

你只需使用 Nullable<T>当然,它是免费的——此外,您还可以获得编译器 + 运行时(装箱)支持。有没有理由不使用 Nullable<T>在这里?

我会看看规范;在此期间,您可能会考虑将运算符(operator)提升为 MyNullable<T> ;与常规 Nullable<T> ,C# 编译器为类型支持的运算符提供“提升”运算符,但您不能自己这样做。您能做的最好的事情就是提供所有明显的,并希望类型支持它;-p 要使用泛型访问运算符,请参见 here , 可免费下载here .

请注意,您可能希望应用适当的“取消”检查 - 即

x + y => (x.HasValue && y.HasValue)
? new MyNullable<T>(x.Value + y.Value)
: new MyNullable<T>();

更新

不同的处理方式看起来与 14.7.4 (ECMA 334 v4)“加法运算符”有关,它是为一系列类型预定义的包括小数(所以这是一个糟糕的测试由我),因为在 14.2.4(相同)“二元运算符重载决议”中,预定义运算符确实得到了特别提及。不过,我并不声称完全理解它。

关于c# - 为什么 C# 编译器不调用隐式转换运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/393701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com