C# 将泛型结构转换为具有不同类型参数的相同泛型结构

C# 将泛型结构转换为具有不同类型参数的相同泛型结构,c#,generics,struct,C#,Generics,Struct,假设我有这样一个基本的类层次结构: 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>(); pu

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

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>();
public struct MyStruct<T>
    where T: BaseClass, new()
{
    public MyStruct(MyStruct<T2> value) 
        where T2: BaseClass, new()
    {
      ...
    }
}
public struct MyStruct
其中T:BaseClass,new()
{
公共MyStruct(MyStruct值)
其中T2:基类,new()
{
...
}
}
编译器不明白我要做什么(似乎无法区分
MyStruct
MyStruct


如何从
MyStruct
内部将
MyStruct
转换为
MyStruct

public struct MyStruct<T>
    where T: BaseClass, new()
{
    // Convert this instance of MyStruct<T> to a new MyStruct<TOut>
    public MyStruct<TOut> ToMyStruct<TOut>()
    {
        ...
    }
}
public struct MyStruct
其中T:BaseClass,new()
{
//将此MyStruct实例转换为新的MyStruct
public MyStruct tomystuct()
{
...
}
}
这样你就可以写:


struct2=struct1.tomystuct()

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

public struct MyStruct<T>
    where T: BaseClass, new()
{
    // Convert this instance of MyStruct<T> to a new MyStruct<TOut>
    public MyStruct<TOut> ToMyStruct<TOut>()
    {
        ...
    }
}
public struct MyStruct
其中T:BaseClass,new()
{
//将此MyStruct实例转换为新的MyStruct
public MyStruct tomystuct()
{
...
}
}
这样你就可以写:

struct2=struct1.tomystuct()
C#没有泛型转换运算符的概念;任何转换运算符(隐式或显式)都必须导入或导出由定义类型的泛型参数完全定义的类型。这意味着
Foo
可以定义与
Bar
之间的转换运算符(反之亦然),
Foo
可以定义与
Bar
之间的转换,但不能定义与
Bar
之间的转换。它还意味着
Foo
可以定义与` Bar之间的转换,但不能定义与` Bar之间的转换。不幸的是,没有办法让转换运算符能够导入或导出具有泛型类型参数的类型,而不是定义类型的参数,即使这些参数会受到约束,从而使强制转换成功

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

顺便说一句,如果结构使用泛型类型参数的唯一目的是定义该类型的公共字段,那么理论上,这种结构可以支持协方差,而不考虑结构是否“可变”,因为将
KeyValuePair
分配给
KeyValuePair
代表将
FordFocus
分配给
车辆
和将
siamescat
分配给
动物
,两者都是类型安全的。然而,这失败了,因为所有装箱结构总是可变的,并且类型的可变方面不能安全地支持协方差;任何转换运算符(隐式或显式)都必须导入或导出由定义类型的泛型参数完全定义的类型。这意味着
Foo
可以定义与
Bar
之间的转换运算符(反之亦然),
Foo
可以定义与
Bar
之间的转换,但不能定义与
Bar
之间的转换。它还意味着
Foo
可以定义与` Bar之间的转换,但不能定义与` Bar之间的转换。不幸的是,没有办法让转换运算符能够导入或导出具有泛型类型参数的类型,而不是定义类型的参数,即使这些参数会受到约束,从而使强制转换成功

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


顺便说一句,如果结构使用泛型类型参数的唯一目的是定义该类型的公共字段,那么理论上,这种结构可以支持协方差,而不考虑结构是否“可变”,因为将
KeyValuePair
分配给
KeyValuePair
代表将
FordFocus
分配给
车辆
和将
siamescat
分配给
动物
,两者都是类型安全的。但是,这失败了,因为所有装箱结构都是可变的,并且类型的可变方面不能安全地支持协方差。

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

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

....
公共静态隐式运算符MyStruct(MyStruct值)
{
返回新的MyStruct(值);
}
公共静态隐式运算符MyStruct(MyStruct值)
{
返回新的MyStruct(值);
}
....
这仅限于已知类型(X,Y,…),但让我编写以下代码:

MyStruct<X> x = new MyStruct<X>(...);
MyStruct<Y> y = x;
MyStruct x=newmystruct(…);
MyStruct y=x;

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

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

....
公共静态隐式运算符MyStruct(MyStruct值)
{
返回新的MyStruct(值);
}
公共静态隐式运算符MyStruct(MyStruct值)
{
返回新的MyStruct(值);
}
....
这仅限于已知类型(X,Y,…),但让我编写以下代码:

MyStruct<X> x = new MyStruct<X>(...);
MyStruct<Y> y = x;
MyStruct x=newmystruct(…);
MyStruct y=x;

在转换运算符中是否有这样做的方法?这样客户端代码就不必显式调用特定的方法了?在转换操作符中有没有这样做的方法?因此,客户端代码不必显式