1

假设我有一个像这样的基本类层次结构:

public abstract class BaseClass { }
public class X : BaseClass { }
public class Y: BaseClass { }

我有一个这样的通用结构:

public struct MyStruct<T>
  where T: BaseClass, new()
{
}

然后我可以创建一个实例,如下所示:

var x = new MyStruct<X>();

现在我想在 上提供一个操作(构造函数或转换运算符)MyStruct,它允许我转换MyStruct<X>MyStruct<Y>

MyStruct<Y> my = new MyStruct<X>();

当我编写如下构造函数时:

public struct MyStruct<T>
    where T: BaseClass, new()
{
    public MyStruct(MyStruct<T2> value) 
        where T2: BaseClass, new()
    {
      ...
    }
}

编译器不明白我要做什么(似乎无法区分MyStruct<T>and MyStruct<T2>)。

我如何从内部转换MyStruct<X>为?MyStruct<Y>MyStruct<T>

4

3 回答 3

3

您不能在构造函数中执行此操作,但您应该能够在结构中编写转换方法,例如:

public struct MyStruct<T>
    where T: BaseClass, new()
{
    // Convert this instance of MyStruct<T> to a new MyStruct<TOut>
    public MyStruct<TOut> ToMyStruct<TOut>()
    {
        ...
    }
}

这将允许您编写:

struct2 = struct1.ToMyStruct<TOut>()

于 2013-09-28T23:13:04.590 回答
2

我使用以下方法使其工作:

public static implicit operator MyStruct<T>(MyStruct<X> value)
{
    return new MyStruct<T>(value);
}

public static implicit operator MyStruct<T>(MyStruct<Y> value)
{
    return new MyStruct<T>(value);
}

....

这仅限于已知类型(X,Y,...),但让我编写以下代码:

MyStruct<X> x = new MyStruct<X>(...);
MyStruct<Y> y = x;
于 2013-10-01T18:52:10.680 回答
2

C# 没有泛型转换运算符的概念;任何转换运算符,无论是隐式还是显式,都必须导入或导出完全由定义类型的泛型参数定义的类型。这意味着Foo<T>可以定义转换运算符 to 或 from Bar<T>(反之亦然),并且Foo<T,U>可以定义转换 to 或 from Bar<U>,但反之则不行。这也意味着 aFoo<T>可以定义与 `Bar 之间的转换,但反之则不行。不幸的是,没有办法让转换运算符可以导入或导出具有超出定义类型的泛型类型参数的类型,即使参数将以强制转换成功的方式进行约束。

这一切意味着人们必须经常使用方法而不是运算符来执行转换(或者,就此而言,执行混合类型的操作)。方法的泛型类型解析非常聪明(至少如果愿意包含一个默认空虚拟参数),但对于操作员来说,它非常有限。

顺便说一句,如果一个结构使用泛型类型参数的唯一目的是定义该类型的公共字段,那么理论上这种结构应该可以支持协变,而不考虑结构是否“可变”,因为aKeyValuePair<FordFocus,SiameseCat>到 aKeyValuePair<Vehicle,Animal>的赋值表示 aFordFocus到 aVehicle和 aSiameseCat到a 的赋值Animal,两者都是类型安全的。然而,这失败了,因为所有盒装结构总是可变的,并且类型的可变方面不能安全地支持协变。

于 2013-09-30T21:46:04.367 回答