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