我做了一个测试用例来说明我遇到的问题。
第一个断言通过,但第二个和第三个都失败了。
有没有办法以不同的方式检查两个失败条件k中的任何一个?如果它不是非常快,我打算按类型缓存结果,那就没关系了。
public interface IParentInterface
{
}
public interface IChildInterface : IParentInterface
{
}
public class ParentClass<T> where T: IParentInterface
{
}
public class ChildClass : ParentClass<IChildInterface>
{
}
public class TestClass
{
public ChildClass Property { get; set; }
}
[TestFixture]
public class ScratchPad
{
[Test]
public void Assignabl()
{
var tc = new TestClass();
var tct = tc.GetType();
var pi = tct.GetProperty("Property");
Assert.IsNotNull(pi);
Assert.IsTrue(typeof(ParentClass<IChildInterface>).IsAssignableFrom(pi.PropertyType));
Assert.IsTrue(typeof(ParentClass<>).IsAssignableFrom(pi.PropertyType));
Assert.IsTrue(typeof(ParentClass<IParentInterface>).IsAssignableFrom(pi.PropertyType));
}
}
答案 0 :(得分:2)
根据设计,你的第二个断言失败了。当你写
public class ParentClass<ParentInterface>
它实际上意味着“ParentInterface”现在是一个类型参数的符号(这样做太混乱了,实际上,它完全让你困惑)。 写
public class ChildClass : ParentClass<ChildInterface>
然后将类型参数(是的,名为“ParentInterface”的那个)设置为ChildInterface类型。因此,Childclass只能分配给ParentClass&lt; ChildInterface&gt;。
最后,你应该确保在定义类型参数时遵循约定,这会让你更加困惑,例如。
public class ParentClass<T>
用“I”标记接口也将大大增强理解,例如
interface IParent { }
interface IChild : IParent { }
我怀疑在我们得到c#4.0之前,你想要的东西是不可能的:
Parent<IChild>
不能转发给
Parent<IParent>
目前没有仿制药的共同/逆转。
答案 1 :(得分:0)
这不是the covariance/contravariance thing吗?
然后它只是C#目前不支持的东西,但C#4.0可能会支持。
答案 2 :(得分:0)
你不能,因为C#3.0不支持这种方差。在C#4.0中,你应该可以。
使用其他示例,假设您有List<ParentInterface>
,并且可以将其分配给List<ChildInterface>
:
List<ParentInterface> parentList = List<ParentInterface>();
List<ChildInterface> childList = parentList;
问题是parentList
的内部存储空间适用于ParentInterface
类型。如果您从ChildInterface
派生了另一个界面:
public interface ParentInterface2 : ChildInterface {}
然后尝试将其添加到childList
,如下所示:
childList.Add(new ParentInterface2Implementation());
您会收到异常,因为childList
实际上是List<ParentInterface>
并且只能存储ParentInterface
的实现,而ParentInterface2
则不是。{/ p>