我试图从泛型类内的静态字段中获取泛型类型的实例值,并且抛出此异常:
无法对类型为Type.ContainsGenericParameters为true的字段执行后期绑定操作
public class ManagerTemplate<Q, T> : IObjectManager
where T : Filmation.Runtime.Engine.ObjectId, new( )
where Q : ManagerTemplate<Q, T>, new( ) {
public readonly static Q Instance = new Q( ); <---- STATIC FIELD
}
private static void FindManagers( ) {
var IObjectManagerType = typeof( IObjectManager );
var managers = IObjectManagerType.Assembly
.GetTypes( )
.Where( t => !t.IsAbstract && t.GetInterfaces().Any( i => i == IObjectManagerType) );
foreach (var manager in managers) {
var fi = manager.GetField( "Instance" );
var instance = fi.GetValue( null ); <--- EXCEPTION
}
}
我尝试使用GetGenericTypeDefinition,但继续引发异常。
我已经在google中搜索过,但是还没有找到可以完成的方法...
有人知道该怎么做吗?
编辑:使用静态属性相同
这是我已经实现的解决方法(尽管我想知道是否可以使用反射来完成):
public static Q Instance { get; private set; }
static ManagerTemplate( ) {
Instance = new Q( );
Environment.Managers.Add( Instance );
}
最佳答案
您不能从通用类型定义public readonly static Q Instance = new Q( );
中获取ManagerTemplate<Q, T>
的值,仅仅是因为Q
没有具体类型。
如果您还不知道Q
的具体类型是什么,如何获得泛型类型定义Q
的实例?简单:您不能。
现在...如果要获取的是某个类型的实例,该类型源自定义了通用类型参数ManagerTemplate<Q, T>
的Q
,那么您实际上想从搜索中排除通用类型参数。
private static IEnumerable<IObjectManager> FindManagers()
{
Type type = typeof(IObjectManager);
IEnumerable<Type> managers = type.Assembly
.GetTypes()
.Where(t => !t.IsAbstract && t.GetInterfaces().Contains(type));
foreach (Type manager in managers)
{
var fi = manager.GetField("Instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (fi != null &&
!fi.FieldType.IsGenericParameter &&
type.IsAssignableFrom(fi.FieldType))
{
yield return (IObjectManager) fi.GetValue(null);
}
}
}
这将为您提供在所有
ManagerTemplate<Q, T>
派生的类中定义的所有“管理器”,这些类定义了Q
类型。关于c# - 从fieldinfo获取通用值会引发异常:“无法执行后期操作...”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18156995/