实例化实现泛型接口的类

本文关键字:泛型接口 实现 实例化 | 更新日期: 2023-09-27 17:54:36

我有一个接口用于指定GetData方法,该方法根据其ID返回类的一个实例

public interface ILabelData<T> {
  T GetData(object id);
}

,也有许多不同的类,这些类实现了接口,当然有成员:

public class BTAC : ILabelData<BTAC> {
  // members...
  // and interface impl:
  public BTAC GetData(object id) {
    return null;
  }
}
public class KTAC : ILabelData<KTAC> {
  // members...
  // and interface impl:
  public KTAC GetData(object id) {
    return null;
  }
}

在调用方法中,我想实例化一个BTAC/KTAC/…类并调用它们的GetData方法。这样做的目的是,在我有了所需的实例之后,我想获得它的成员和属性。获取成员和属性不是我问题的一部分。)

ILabelData<object> o = Activator.CreateInstance(type, new object[] { myID });
^^^^^^^^^^^^^^^^^^^^
object data = o.GetData(myID);

问题是编译错误不能隐式地将类型'object'转换为'ILabelData<对象">

在实例化适当的类之后,当然我也需要成员和属性,所以返回ILabelData类型的对象是不够的。

我怎样才能得到这样一个对象?工厂之类的?

实例化实现泛型接口的类

    你把工厂和实体搞混了。这是不必要的-让GetData成为BTAC上的实例方法真的没有意义。
  1. Activator.CreateInstance返回object -您需要显式地将其转换为您想要的类型。
  2. 这两个类型都没有实现ILabelData<object>

问题是,代码是这样的,有ILabelData泛型根本没有意义!如果您打算使用object,请从ILabelData中删除泛型参数,然后这样做:

var o = (ILabelData)Activator.CreateInstance(type, new object[] { myID });
var data = o.GetData(myID);

让接口(和GetData方法)泛型只有在你实际使用它的时候才有意义

如果通常直接使用,并且只在少数特殊情况下需要这样使用它(为什么?),您还可以使接口协变:

public interface ILabelData<out T>
{
  T GetData(object id);
}

这将允许您在BTAC中实现ILabelData<BTAC>,为您提供"用户友好"的BTAC GetData(object)方法,同时仍然允许您对ILabelData<object>进行显式转换。即便如此,我也会避免这种方法。它的气味。

工作代码在这里

var instances = (from t in System.Reflection.Assembly.GetCallingAssembly().GetTypes()
                        where t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ILabelData<>))
                                 && t.GetConstructor(Type.EmptyTypes) != null
                        select Activator.CreateInstance(t)).ToList();
        foreach (dynamic item in instances)
        {
            var res = item.GetData(1);
        }