【问题标题】: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)
    }
}

谢谢

【问题讨论】:

    标签: c# generics casting operator-overloading


    【解决方案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&lt;U&gt;((U)a.Item)

    您尝试将基类分配给继承的类,这是不可能的。

    假设 T(基类)是 Stream 类型,而 U 是 MemoryStream(继承类)类型,您不能将 Stream 分配给 MemoryStream 类型的变量。

    【讨论】:

    • 当然可以,如果引用将对象屏蔽为 Stream,但实际上是 MemoryStream,那么您当然可以将其转换为 Memory Stream。这是一种合法的方法,问题是您实际上不能在运算符重载上指定通用约束...
    • ...如果您将我拥有的代码表示为方法而不是运算符重载,它将编译
    【解决方案3】:

    我认为简短的回答是“不可能。尝试改用一种方法”

    似乎也被这个问题所欺骗 Solution for overloaded operator constraint in .NET generics

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-04
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      相关资源
      最近更新 更多