我如何解决Type.IsAssignableFrom不使用继承的接口?

时间:2009-01-08 19:59:18

标签: c#

我做了一个测试用例来说明我遇到的问题。

第一个断言通过,但第二个和第三个都失败了。

有没有办法以不同的方式检查两个失败条件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));

    }

}

3 个答案:

答案 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>