2009-11-18 7 views
0

У меня есть общий метод с новым() ограничением. У меня есть вызов этого метода с абстрактным типом, который, конечно же, не будет компилироваться. Я хочу сохранить общий вызов, но надеялся, что во время выполнения я смогу определить, что производный класс удовлетворяет компилятору. Вызов будет выглядеть примерно так:Определение производного типа класса во время выполнения

var result = MyGenericMethod<FindDerivedClass(myAbstractClass)>(); 

Я попробовал typeof(), но это не работает.

ответ

0

Плохая идея, которую DerivedClass вы хотите взять? Что делать, если их больше? что, если нет DerivedClass?

Вы можете передать тип в качестве параметра типа параметра, а не метод типа класса:

abstract class MyAbstractClass<T> where T : MyAbstractClass<T>, new() 
{ 
    T MyMethod() { return new T(); } 
} 
1

У меня есть универсальный метод с новым() ограничения. У меня есть вызов этого метода с абстрактным типом, который, конечно же, не будет компиляции. Я хочу сохранить общий вызов, но надеялся, что во время выполнения я смогу определить, что производный класс удовлетворяет компилятору.

Это не сборник, а скорее фактические семантика вам нужно беспокоиться о. У вас есть метод с ограничением new() - это говорит о том, что методу необходимо создать экземпляр объекта T, который он передал. Вы хотите передать абстрактный класс как T - но что бы это значило? Что должен делать общий метод, когда он хочет создать экземпляр?

Вам необходимо решить ответы на следующие вопросы: Если для метода не требуется создавать экземпляр T, почему у него есть ограничение new()? Если ему нужно создать экземпляр T, что он должен делать, если вам каким-то образом удается заставить компилятор принять абстрактный класс как T?

1

Чтобы использовать обобщения во время выполнения, вам необходимо использовать отражение - просмотрите все типы сборки в соответствии с тем, который вы хотите (вы можете использовать Type.IsSubclassOf), получите MethodInfo для общего метода, который вы хотите вызвать на него, затем подставим в фактического типа вы хотите вызвать его с MethodInfo.MakeGenericMethod, и вызвать его с помощью Invoke

0

Если MyGenericMethod является метод экземпляра:

var method = typeof(this).GetMethod("MyGenericMethod", Type.EmptyTypes); 
method = method.MakeGenericMethod(new Type[] { FindDerivedClass(myAbstractClass) }); 
Action action = (Action)Delegate.CreateDelegate(typeof(Action), this, method); 
action(); 

Если MyGenericMethod статический метод:

var method = typeof(TypeWithGenericMethod).GetMethod("MyGenericMethod", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null); 
method = method.MakeGenericMethod(new Type[] { FindDerivedClass(myAbstractClass) }); 
Action action = (Action)Delegate.CreateDelegate(typeof(Action), method); 
action(); 

Если MyGenericMethod возвращает значение, используйте Func<ReturnType> вместо делегата Action.

Смежные вопросы