我知道如何强制类型参数成为subtype另一种类型:
public interface IMapping<T2>
{
public void Serialize<T3>(T3 obj)
where T3 : T2;
}
...
var mapping = MapManager.Find<Truck>();
mapping.Serialize(new TonkaTruck());
有没有办法强制类型参数成为超类型另一种类型的?
public interface IMapping<T2>
{
public void IncludeMappingOf<T1>()
where T2 : T1; // <== doesn't work
}
...
var mapping = MapManager.Find<Truck>();
// Truck inherits Vehicle
// Would like compiler safety here:
mapping.IncludeMappingOf<Vehicle>();
mapping.Serialize(new TonkaTruck());
目前,我必须在运行时使用 T1 和 T2 进行比较IsSubclassOf
inside IncludeMappingOf
。编译安全的解决方案会更好。有任何想法吗?
EDIT:更改了示例以减少设计臭味。
NOTE:链接的问题非常相似,但没有给出合适的答案。希望这个问题也能对这个问题有所启发。
EDIT #2:
更简单的例子:
public class Holder<T2>
{
public T2 Data { get; set; }
public void AddDataTo<T1>(ICollection<T1> coll)
//where T2 : T1 // <== doesn't work
{
coll.Add(Data); // error
}
}
...
var holder = new Holder<Truck> { Data = new TonkaTruck() };
var list = new List<Vehicle>();
holder.AddDataTo(list);
编译器:参数类型“T2”不可分配给参数类型“T1”。是的,我知道,我试图让编译器只允许 T2 可分配给参数类型 T1 的情况!
虽然 w0lf 的答案给出了直接的解决方案,但我想给出一些背景解释。
当你写类似的东西时
class C<A> where A : B
or
void F<A>() where A : B
形式的约束A : B
一定有A
作为所声明的类、接口、方法等的泛型类型参数之一。
您面临的错误是not因为您已将当前声明的泛型类型参数放置在冒号的右侧(这是合法的) - 这是因为您已将外部声明(不是当前声明)的泛型类型参数放置在左侧结肠的。
如果你想形成一个约束A : B
在某些声明中,A
必须在该声明和范围中引入A
必须小于或等于范围B
。这是一个实用的语言限制的原因是,对于任何泛型类型参数T
,它隔离了有关类型约束的任何推理T
到单个声明,其中T
正在介绍中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)