我有一个通用的基类,我最终会有很多派生类。 我正在尝试编写一个函数来返回所有这些子类,但到目前为止我尝试的所有东西都没有用。
public abstract class Index<T>
where T : class
{
public abstract string IndexName { get; }
public abstract string TypeName { get; }
public abstract Expression<Func<T, IConvertible>> IdFieldSelector { get; }
public string MakeSearchId(T item)
{
return ToSearchId(IdFieldSelector.Compile().Invoke(item));
}
public string MakeSearchId(IConvertible idValue)
{
return ToSearchId(idValue);
}
private static string ToSearchId(IConvertible idValue)
{
return idValue.ToString(CultureInfo.InvariantCulture);
}
}
示例子类:
public class SurveyChangedIndex : Index<SurveyChanged>
{
public override string IndexName => "reviews";
public override string TypeName => "review";
public override Expression<Func<SurveyChanged, IConvertible>> IdFieldSelector => sc => sc.SurveyResponseId;
}
示例功能:
var indexBase = typeof(Index<>);
var indexes = Assembly.GetAssembly(indexBase)
.GetTypes()
.Where(type =>
type != indexBase &&
!type.IsInterface &&
!type.IsAbstract &&
type.BaseType == indexBase)
.ToList();
答案 0 :(得分:1)
您可以执行以下操作(C#7语法如下):
public static IEnumerable<Type> GetAllDescendantsOf(
this Assembly assembly,
Type genericTypeDefinition)
{
IEnumerable<Type> GetAllAscendants(Type t)
{
var current = t;
while (current.BaseType != typeof(object))
{
yield return current.BaseType;
current = current.BaseType;
}
}
if (assembly == null)
throw new ArgumentNullException(nameof(assembly));
if (genericTypeDefinition == null)
throw new ArgumentNullException(nameof(genericTypeDefinition));
if (!genericTypeDefinition.IsGenericTypeDefinition)
throw new ArgumentException(
"Specified type is not a valid generic type definition.",
nameof(genericTypeDefinition));
return assembly.GetTypes()
.Where(t => GetAllAscendants(t).Any(d =>
d.IsGenericType &&
d.GetGenericTypeDefinition()
.Equals(genericTypeDefinition)));
}
这将返回从指定的泛型类型定义直接或间接继承的任何类型。
在以下情形中:
class Base { }
class Base<T>: Base { }
class Foo : Base<int> { }
class Bar : Base<string> { }
class Frob : Bar { }
class FooBar: Base { };
var genericTypeDefinition = typeof(Base<>);
var types = Assembly.GetExecutingAssembly()
.GetAllDescendantsOf(genericTypeDefinition)));
GetAllDescendantsOf
将输出Foo
,Bar
和Frob
。
答案 1 :(得分:0)
这应解决您的代码:
var indexes = Assembly.GetAssembly(indexBase)
.GetTypes()
.Where(type =>
type != indexBase &&
!type.IsInterface &&
!type.IsAbstract &&
type.BaseType.IsAssignableFrom(indexBase))
.ToList();