using System;
using System.Collections.Generic;
using System.Text;
namespace Hardcase.Common.Utils {
public static class GenericHelper {
private static Type[] FindGenericArguments(Type current_type, Type generic_definition) {
if (current_type.IsGenericType) {
Type base_generic_definition = current_type.GetGenericTypeDefinition();
if (base_generic_definition.Equals(generic_definition)) {
return current_type.GetGenericArguments();
}
}
Type base_type = current_type.BaseType;
if (base_type != null)
return FindGenericArguments(base_type, generic_definition);
return null;
}
private static Type[] FindInterfaceGenericArguments(Type current_type, Type generic_definition) {
if (current_type.IsGenericType) {
Type base_generic_definition = current_type.GetGenericTypeDefinition();
if (base_generic_definition.Equals(generic_definition)) {
return current_type.GetGenericArguments();
}
}
foreach (Type base_type in current_type.GetInterfaces()) {
Type[] result = FindInterfaceGenericArguments(base_type, generic_definition);
if (result != null)
return result;
}
return null;
}
public static Type[] GetGenericArguments(Type reflected_type, Type generic_base_type) {
if (reflected_type == null)
throw new ArgumentNullException("reflected_type");
if (generic_base_type == null)
throw new ArgumentNullException("generic_base_type");
if (!generic_base_type.IsGenericTypeDefinition)
throw new ArgumentException(string.Format("Type {0} is not valid generic type definition.", generic_base_type), "generic_base_type");
if (generic_base_type.IsInterface) {
if (reflected_type.IsInterface)
return FindInterfaceGenericArguments(reflected_type, generic_base_type);
else {
foreach (Type iface in reflected_type.GetInterfaces()) {
Type[] result = FindInterfaceGenericArguments(iface, generic_base_type);
if (result != null)
return result;
}
return null;
}
} else
return FindGenericArguments(reflected_type, generic_base_type);
}
}
}
Задачка на рефлексию :о)
class A<T> { }
class B : A<int> { }
class C : A<string> { }
и метод:
MyFunc(object o) { }
в метод передаётся объект класса B или класса C. (которые оба унаследованы от A<T>!)
так вот в методе нужно получить объект класса Type который содержит тип параметра обобщенного класса A.
Другими словами, если я вызываю MyFunc(new B()), мне нужно получить typeof(int), если MyFunc(new С()) - то typeof(string).
PS метод нельзя делать generic!
Всё, нашёл удовлетворяющее меня решение, всем спасибо )
Цитата: Ordos
Другими словами, если я вызываю MyFunc(new B()), мне нужно получить typeof(int), если MyFunc(new С()) - то typeof(string).
PS метод нельзя делать generic!
PS метод нельзя делать generic!
Покопавшись в закромах нашел такой класс:
Код:
Использовать видимо вот так:
Код:
Type[] ty_args = GenericHelper.GetGenericArguments(typeof(B), typeof(A<>));
Очень благодарен, большое спасибо, это идеальное решение. )