实例化实现泛型接口的类
本文关键字:泛型接口 实现 实例化 | 更新日期: 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类型的对象是不够的。我怎样才能得到这样一个对象?工厂之类的?
- 你把工厂和实体搞混了。这是不必要的-让
-
Activator.CreateInstance
返回object
-您需要显式地将其转换为您想要的类型。 - 这两个类型都没有实现
ILabelData<object>
。
GetData
成为BTAC
上的实例方法真的没有意义。问题是,代码是这样的,有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);
}