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

将简单对象强制转换为简单的通用接口

  •  3
  • Jiji  · 技术社区  · 6 年前

    我正在寻找一种将对象转换为简单接口和派生自简单接口的通用接口的方法。

    以下是我的示例:

    interface INonGeneric
    {
    
    }
    
    interface IGeneric<T> : INonGeneric where T : ITypeParameter
    {
        T Build();
    }
    
    interface ITypeParameter
    {
    
    }
    
    class TypeClass : ITypeParameter
    {
    
    }
    

    这就是我尝试的设计。如果我对泛型的理解有缺陷,我想是的,那么这个错误对你来说是显而易见的。

    然后创建要使用的类:

    class MyClass : MyClassBase<TypeClass>
    {
        public override TypeClass Build()
        {
            return new TypeClass();
        }
    }
    
    abstract class MyClassBase<T> : IGeneric<T> where T : ITypeParameter
    {
        public abstract T Build();
    }
    

    然后我试着让他们这样:

    void Main()
    {
        var myClass = new MyClass();
    
        var cast1 = myClass as INonGeneric;
        if(cast1 != null) Console.WriteLine("cast 1 works!"); //THIS WORKS
        var cast2 = TestCast<ITypeParameter>(myClass);
        if(cast2 != null) Console.WriteLine("cast 2 works!"); //THIS DOES NOT WORK
    }
    

    任何帮助都将不胜感激。

    编辑:抱歉,我忘了输入TestCast方法。这是:

    IGeneric<T> TestCast<T>(INonGeneric obj) where T : ITypeParameter
    {
        return obj as IGeneric<T>;
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   AliJP    6 年前

    由于协方差问题,这不起作用。 请考虑此示例代码。

    var liInt = new List<int>() { 1,2,3};
    var liObj = List<object>(liInt);
    

    之后,您可以向liObj添加一些非整数值,显然,这是不好的。

    bool b = false;
    liObj.Add(b);
    

    为了防止出现这种情况,应该隐式地告诉您,您只在返回位置使用泛型类型,而不在输入中使用。例如:

    interface IGeneric<out T> : INonGeneric where T : ITypeParameter
    

    有关更多信息,请参阅以下链接: http://tomasp.net/blog/variance-explained.aspx/