[英]Generic type casting using Activator.CreateInstance
I have an interface 我有一个界面
public interface ISomething<TValue>
where TValue : IConvertible
{
...
}
Then I also have some non-generic class with a generic method: 然后,我还有一些具有泛型方法的非泛型类:
public class Provider
{
public static void RegisterType<TValue>(ISomething<TValue> instance)
where TValue : IConvertible
{
...
}
}
This seems all fine until I want to automatically register all applicable types in my particular assembly. 直到我要在我的特定程序集中自动注册所有适用的类型之前,这似乎还不错。
public void InitializeApp()
{
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
{
// ERROR
Provider.RegisterType(Activator.CreateInstance(t));
}
}
This code results in error as argument type can't be inferred from usage. 此代码导致错误,因为无法从用法中推断出参数类型。 I should either
我要么
RegisterType
(I don't think I can do this due to dynamic nature of my code) or RegisterType
提供显式的通用类型(由于代码的动态性质,我不认为可以做到这一点)或 Activator.CreateInstance
to appropriate type so argument type could be inferred from usage Activator.CreateInstance
为适当的类型,以便可以从用法中推断出参数类型 But I don't know how to do either? 但是我也不知道该怎么办? Maybe there's a third option I'm not aware of.
也许还有我不知道的第三种选择。
Generics are a compile-time feature, meaning that the generic types must be known at compile time. 泛型是编译时的功能,这意味着必须在编译时知道泛型类型。 So your
RegisterType
method can't be used when you only know the type at runtime, since there's no way for the compiler to deduce the generic parameter. 因此,当您仅在运行时知道类型时,就不能使用
RegisterType
方法,因为编译器无法推断出通用参数。
You have a couple options here. 您在这里有几个选择。 You can either use reflection to call the correct version of
RegisterType
(as suggested in the comments), or you can create an additional non-generic overload of RegisterType
that accepts an object and figures out the execution-time type from that. 您可以使用反射来调用正确版本的
RegisterType
(如注释中所建议),或者可以创建RegisterType
的其他非泛型重载,该重载接受对象并从中找出执行时类型。
For the former, that would look something like this: 对于前者,它看起来像这样:
public void InitializeApp()
{
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ISomething<>).IsAssignableFrom(T)))
{
var methodInfo = typeof( Provider ).GetMethod( "RegisterType", BindingFlags.Static );
var registerTypeMethod = methodInfo.MakeGenericMethod( t );
registerTypeMethod.Invoke( null, new[] { Activator.CreateInstance(t) } );
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.