在 C# 中是不是可以通过以下方式重载泛型强制转换运算符?
Posted
技术标签:
【中文标题】在 C# 中是不是可以通过以下方式重载泛型强制转换运算符?【英文标题】:Is it possible in C# to overload a generic cast operator in the following way?在 C# 中是否可以通过以下方式重载泛型强制转换运算符? 【发布时间】:2009-06-22 05:30:22 【问题描述】:只是想知道在 C# 3.5 中是否有任何方法可以表示以下代码:
public struct Foo<T>
public Foo(T item)
this.Item = item;
public T Item get; set;
public static explicit operator Foo<U> ( Foo<T> a )
where U : T
return new Foo<U>((U)a.Item)
谢谢
【问题讨论】:
【参考方案1】:转换运算符不能是通用的。在规范第 10.10 节中,这是转换操作符声明符的格式:
转换操作符声明符: 隐式运算符 type ( type identifier ) 显式运算符 type (type identifier)
将其与方法头进行比较:
方法头: 属性opt 方法修饰符opt 部分opt 返回类型 member-name type-parameter-listopt (formal-parameter-listopt ) 类型参数约束子句opt
(抱歉格式化 - 不知道如何做得更好。)
请注意,运算符格式不包括类型参数列表或类型参数约束。
【讨论】:
即使我们确实支持用户定义的通用转换,这仍然是非法的。定义替换内置转换的转换是非法的。如果 T 和 U 是同一类型,就会这样做;您将替换身份转换。 由于转换是由编译器决定的,如果 T 和 U 是相同的类型,那么它不会使用用户定义的转换,并且是合法的。【参考方案2】:您的代码归结为:return new Foo<U>((U)a.Item)
您尝试将基类分配给继承的类,这是不可能的。
假设 T(基类)是 Stream
类型,而 U 是 MemoryStream
(继承类)类型,您不能将 Stream
分配给 MemoryStream
类型的变量。
【讨论】:
当然可以,如果引用将对象屏蔽为 Stream,但实际上是 MemoryStream,那么您当然可以将其转换为 Memory Stream。这是一种合法的方法,问题是您实际上不能在运算符重载上指定通用约束... ...如果您将我拥有的代码表示为方法而不是运算符重载,它将编译【参考方案3】:我认为简短的回答是“不可能。尝试改用一种方法”
似乎也被这个问题所欺骗 Solution for overloaded operator constraint in .NET generics
【讨论】:
以上是关于在 C# 中是不是可以通过以下方式重载泛型强制转换运算符?的主要内容,如果未能解决你的问题,请参考以下文章