代码之家  ›  专栏  ›  技术社区  ›  Jay

如何处理Type.IsAssignableFrom不使用继承接口?

c#
  •  1
  • Jay  · 技术社区  · 16 年前

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

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

    有没有一种方法可以用不同的方式检查两种故障情况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 回复  |  直到 16 年前
        1
  •  2
  •   flq    16 年前

    您的第二个断言是按设计失败的。当你写作时

    public class ParentClass<ParentInterface>
    

    它实际上意味着“ParentInterface”现在是一个类型参数的符号(这样做太令人困惑了,实际上,它完全让您困惑了)。 写作

    public class ChildClass : ParentClass<ChildInterface>
    

    然后将yout类型参数(是的,名为“ParentInterface”)设置为ChildInterface类型。因此,Childclass只能分配给ParentClass<ChildInterface>。

    最后,您应该确保在定义类型参数时遵循约定,这将大大减少您的困惑,例如。

    public class ParentClass<T>
    

    用“I”标记接口也将大大增强理解,例如。

    interface IParent { }
    interface IChild : IParent { }
    

    我怀疑你想要的东西在我们得到c#4.0之前是不可能的:

    Parent<IChild> 
    

    不可分配给

    Parent<IParent>
    

    目前没有泛型的协/反方差。

        2
  •  0
  •   peSHIr    16 年前

    这不是吗 the covariance/contravariance thing ?

    那只是C目前不支持的东西,但C 4.0可能支持。

        3
  •  0
  •   casperOne    16 年前

    你不能,因为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());
    

    你会得到一个例外,因为 儿童名单 真的是 列表<父界面> 并且只能存储 父接口 ,其中 ParentInterface2 不是。