泛型类型上的隐式运算符
使用像下面这样的隐式运算符有什么问题吗:
//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;
}
}
我想我可以通过这种方式将对象的实例视为值类型,但由于我从未见过这样的示例,所以我想也许有一个原因不去做有人可以指出的事情吗?
在我的实际代码中,我正在考虑将其作为数据抽象层的一部分,以便我可以返回具有描述底层数据的信息的对象,但允许逻辑代码在需要了解所有信息时将其视为值类型是值,同时使用泛型保持一切良好和类型安全。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果满足以下所有条件:
所有
MyClass
类型的可能值(如果不是值,则包括null
type!) 映射到T
隐式运算符永远不会抛出异常(甚至对于
null
也不会!)< /p>隐式转换具有语义意义,并且不会让客户端程序员感到困惑
,那么这没有什么问题。当然,您可以做这三件事中的任何一件,但这将是糟糕的设计。特别是,抛出异常的隐式运算符可能很难调试,因为调用它的地方并没有说明它正在被调用。
例如,考虑
T?
没有到T
的隐式转换(其中T
当然是值类型)。如果存在这样一个隐式运算符,则当T?
为 null 时,它必须抛出异常,因为没有明显的值可以将null
转换为对T?
有意义的值。 em>任何值类型T
。让我举一个例子,我在调试隐式运算符引发的问题时遇到了麻烦:
这里,
GetSomething
返回了我编写的类型,该类型具有用户定义的到string
的隐式转换代码>.我绝对确定GetSomething
永远不会返回null
,但我得到了NullReferenceException
!为什么?因为上面的代码不相当于但是
现在你可以看到
null
来自哪里了!If all of the following are true:
all possible values of your
MyClass<T>
type (includingnull
if it’s not a value type!) map to a valid value ofT
the implicit operator never throws (not even for
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?
has no implicit conversion toT
(whereT
is, of course, a value type). If there was such an implicit operator, it would have to throw when theT?
is null, as there is no obvious value to convertnull
to that would make sense for any value typeT
.Let me give an example where I had trouble debugging an issue where the implicit operator threw:
Here,
GetSomething
returned something of a type I wrote which has a user-defined implicit conversion tostring
. I made absolutely sure thatGetSomething
could never returnnull
, and yet I got aNullReferenceException
! Why? Because the above code is not equivalent tobut to
Now you can see where the
null
came from!这是一个很棒的模式。请记住,为了将其用作
T
类型的变量,您必须将其显式转换为T
,或者将其分配给T
类型的变量代码>T。转换将在方法调用和其他采用T
的事情(例如您的加法示例)中自动进行。无需赋值的隐式转换?
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 toT
, or assign it to a variable of typeT
. The cast will take place automatically in method calls and other things (such as your addition example) that take aT
.Implicit conversion without assignment?