简体   繁体   English

泛型类型的隐式运算符

[英]implicit operator on generic types

Is there anything wrong with using an implicit operator like the following:使用如下所示的隐式运算符有什么问题吗:

//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;
    }
}

I was thinking I could treat as instance of the object as a value type this way, but seeing as I've never seen an example of this I thought maybe there was a reason not to do something like this that someone could point out?我想我可以用这种方式将对象的实例视为值类型,但是看到我从未见过这样的例子,我想也许有理由不做这样的事情,有人可以指出?

In my actual code I was thinking of doing this as part of a data abstraction layer, so that I could return objects with information describing the underlying data, but allow the logic code to treat it as a value type when all it needs to know about is the value, and at the same time keep it all nice and type safe with the generics.在我的实际代码中,我正在考虑将其作为数据抽象层的一部分,以便我可以返回带有描述底层数据的信息的对象,但允许逻辑代码在需要了解所有信息时将其视为值类型是值,同时使用泛型保持它的​​完整性和类型安全。

If all of the following are true:如果以下所有情况都为真:

  • all possible values of your MyClass<T> type (including null if it's not a value type!) map to a valid value of T MyClass<T>类型的所有可能值(如果它不是值类型,则包括null !)映射到T的有效值

  • the implicit operator never throws (not even for null !)隐式运算符从不抛出(甚至对于null也不抛出!)

  • the implicit conversion makes semantic sense and is not confusing to the client programmer隐式转换具有语义意义并且不会让客户端程序员感到困惑

then there is nothing wrong with this.那么这没有任何问题。 Of course you could do any of these three things, but it would be bad design.当然,你可以做这三件事中的任何一件,但这将是糟糕的设计。 In particular, an implicit operator that throws can be very hard to debug because the place where it is called doesn't say that it is being called.特别是,抛出的隐式运算符可能很难调试,因为它被调用的地方并没有说它正在被调用。

For example, consider that T?例如,考虑T? has no implicit conversion to T (where T is, of course, a value type).没有隐式转换为T (其中T是,当然,一个值类型)。 If there was such an implicit operator, it would have to throw when the T?如果有这样一个隐式操作符,它会在T? is null, as there is no obvious value to convert null to that would make sense for any value type T .是 null,因为没有明显的值可以将null转换为对任何值类型T都有意义的值。


Let me give an example where I had trouble debugging an issue where the implicit operator threw:让我举一个例子,我在调试隐式运算符抛出的问题时遇到问题:

public string Foo()
{
    return some_condition ? GetSomething() : null;
}

Here, GetSomething returned something of a type I wrote which has a user-defined implicit conversion to string .在这里, GetSomething返回了我编写的某种类型的东西,它具有用户定义的到string隐式转换。 I made absolutely sure that GetSomething could never return null , and yet I got a NullReferenceException !绝对确定GetSomething永远不会返回null ,但我得到了一个NullReferenceException Why?为什么? Because the above code is not equivalent to因为上面的代码等价于

return some_condition ? (string)GetSomething() : (string)null;

but to但要

return (string)(some_condition ? GetSomething() : (Something)null);

Now you can see where the null came from!现在您可以看到null来源了!

That's a great pattern.这是一个很棒的模式。 Just keep in mind that in order to use it as a variable of type T , you have to either explicitly cast it to T , or assign it to a variable of type T .请记住,为了使用它作为类型的变量T ,你必须明确地将其转换为T ,或将其分配给类型的变量T The cast will take place automatically in method calls and other things (such as your addition example) that take a T .强制转换将在方法调用和其他采用T事情(例如您的加法示例)中自动发生。

Implicit conversion without assignment? 没有赋值的隐式转换?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM