泛型类型的隐式运算符

asa*_*yer 8 c# generics implicit-conversion

使用隐式运算符有什么问题,如下所示:

//linqpad c# program example
void Main()
{
    var testObject = new MyClass<int>() { Value = 1 };

    var add = 10 + testObject; //implicit conversion to int here
    add.Dump(); // 11
}

class MyClass<T>
{
    public T Value { get; set; }
    public static implicit operator T (MyClass<T> myClassToConvert)
    {
        return myClassToConvert.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想我可以这样对待为对象的值类型的实例,但看到我从来没有见过这样我想也许有一个理由的例子并不做这样的事情,有人能指出?

在我实际的代码,我想这样的数据抽象层的一部分,这样我就可以用信息返回对象描述的基础数据,但允许逻辑代码把它当作一个值类型时都需要知道是值,同时保持一切美观,并与泛型类型安全.

Tim*_*mwi 10

如果满足以下所有条件:

  • 您的MyClass<T>类型的所有可能值(包括null它是否为值类型!)映射到有效值T

  • 隐式运算符永远不会抛出(甚至不是null!)

  • 隐式转换使语义更有意义,并且不会让客户端程序员感到困惑

那么这没什么不对.当然,你可以做这三件事中的任何一件,但这将是糟糕的设计.特别是,抛出的隐式运算符可能非常难以调试,因为调用它的位置并不表示正在调用它.

例如,考虑T?没有隐式转换T(T当然,值类型).如果存在这样的隐式运算符,则必须在T?为null 时抛出,因为没有明显的值可以转换null为对任何值类型都有意义的值T.


让我举一个例子,我在调试隐式运算符抛出的问题时遇到问题:

public string Foo()
{
    return some_condition ? GetSomething() : null;
}
Run Code Online (Sandbox Code Playgroud)

在这里,GetSomething返回类型我写它有一个用户定义的隐式转换的东西string.我做绝对肯定的是GetSomething永远无法返回null,但我得到了NullReferenceException!为什么?因为上面的代码等同于

return some_condition ? (string)GetSomething() : (string)null;
Run Code Online (Sandbox Code Playgroud)

但是

return (string)(some_condition ? GetSomething() : (Something)null);
Run Code Online (Sandbox Code Playgroud)

现在你可以看到它null来自哪里!