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

显式转换的泛型类型用法[重复]

  •  1
  • Belurd  · 技术社区  · 7 年前

    我有一个代码片段:

    public interface IMyInternalClass
    {
    }
    
    public class MyInternalClass : IMyInternalClass
    {
    }
    
    public interface IMyClass
    {
        T GetInternalObject<T>();
    }
    
    public class MyClass: IMyClass
    {
        private readonly MyInternalClass _internalObject;
    
        public T GetInternalObject<T>()
        {
            return (T)(IMyInternalClass)_internalObject;
        }
    
        public MyClass(MyInternalClass internalObject)
        {
            _internalObject = internalObject;
        }
    }
    

    GetInternalObject<T> 用法:

    IMyInternalClass internalObject = myClass?.GetInternalObject<IMyInternalClass>();
    

    如果我尝试使用显式转换 return (T)_internalObject; 无法将类型“MyInternalClass”转换为“T” "

    那么,在不涉及这个代码示例的设计的情况下,我为什么要将它显式转换为 (IMyInternalClass)

    还有一个问题 Cannot convert type: why is it necesssary to cast twice? 在这种情况下。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Community Mohan Dere    6 年前

    你为什么要投给我 object 第一?

    _internalObject 是一种 MyInternalClass ,而您正试图将此 T . T 可以是任何类型,所以编译器想,“我很确定你肯定不能强制转换 任何类型的。”。如果你投给 对象 对象 在运行时可以是任何类型,因此可以强制转换为任何类型。“

    根据C#spec第6.2.7节“涉及类型参数的显式转换”:

    给定类型参数T存在以下显式转换:

    • 从T的有效基类C到T,从C的任何基类到T。在运行时,如果T是值类型,则转换将作为取消装箱转换执行。否则,转换将作为显式引用转换或标识转换执行。
    • ...

    有效基类 是 对象


    也就是说,你在这里做的似乎是个坏主意。这段代码非常不安全。您可以将任何类型传递到 ,但只有 IMyInternalClass MyInternalClass 为…工作

    因此,这似乎是对泛型的滥用。你只需要返回一个 或 :

    public MyInternalClass GetInternalObject()
    {
        return _internalObject;
    }
    // or
    public IMyInternalClass GetInternalObject()
    {
        return _internalObject;
    }