如何针对类型的迭代执行类型为 <T> 的方法?
How can I execute a method with type <T> against an iteration of types?
抱歉奇怪的问题措辞。我理解这个概念,但我今天 google 技能不足。
我有一个方法可以让我指定一个泛型用于它的工作。传入的任何 class 将继承 "BaseProduct" 的 class。这允许我编写如下代码。
SyncProductsByType<PublicationProduct>();
SyncProductsByType<ApparelProduct>();
.... etc
我只想在基类型的子classes 上做一个 foreach,但我无法获得正确的语法。
到目前为止,我有:
Type parentType = typeof(BaseProduct);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
IEnumerable<Type> subclasses = types.Where(t => t.BaseType == parentType);
但是在 foreach 中使用是完全错误的。我不知道该怎么做:
foreach (<T> subclasse yadda yadda) {
SyncProductsByType<something?>();
}
那还差得远。谢谢
编辑:
我不认为这是重复的,因为假设我正在尝试在所有 class 类型的类型中调用一个方法。不,我想做的是针对单个方法调用针对所有派生类型的方法。
您可以执行以下操作:
public class Test
{
public static void SyncProductsByType<T>() where T : BaseProduct
{
// this method is a simple wrapper with constraint
SyncProductsByType(typeof(T));
}
public static void SyncProductsByType(Type type)
{
// decide whether this should public, private or internal
if (type.BaseType != typeof(BaseProduct))
throw new ArgumentOutOfRangeException(nameof(type));
// do work
}
}
public abstract class BaseProduct
{
}
public class ApparelProduct : BaseProduct
{
}
您可以找到所有后代 类,然后以这种方式调用泛型方法:
class Program
{
class BaseClass
{
public static void Generic<T>() where T : BaseClass
{
Console.WriteLine(typeof(T).Name);
}
}
class FirstClass : BaseClass
{
}
class SecondClass : BaseClass
{
}
static void Main(string[] args)
{
MethodInfo method = typeof(BaseClass).GetMethod("Generic");
foreach (var item in Assembly.GetExecutingAssembly().GetTypes()
.Where(myType => myType.IsClass && myType.IsSubclassOf(typeof(BaseClass))))
{
MethodInfo generic = method.MakeGenericMethod(item);
generic.Invoke(null, null);
}
}
}
编辑:
稍微优化一下。
我想你要找的是 Type.IsSubclassOf 这个检查一个类型是否是另一个类型的子类。使用所述 Type
对象调用方法的唯一方法是获取通用定义 MethodInfo
,然后使用 MakeGenericMethod
创建一个通用方法,该方法将 T
设置为指定的Type
,例如:
Type parentType = typeof(BaseProduct);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
var genericDefinition = typeof(BaseClass).GetMethod("SyncProductsByType");
foreach (Type type in types)
{
if (type.IsSubclassOf(parentType))
{
genericDefinition.MakeGenericMethod(type).Invoke(instance, null);
}
}
抱歉奇怪的问题措辞。我理解这个概念,但我今天 google 技能不足。
我有一个方法可以让我指定一个泛型用于它的工作。传入的任何 class 将继承 "BaseProduct" 的 class。这允许我编写如下代码。
SyncProductsByType<PublicationProduct>();
SyncProductsByType<ApparelProduct>();
.... etc
我只想在基类型的子classes 上做一个 foreach,但我无法获得正确的语法。 到目前为止,我有:
Type parentType = typeof(BaseProduct);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
IEnumerable<Type> subclasses = types.Where(t => t.BaseType == parentType);
但是在 foreach 中使用是完全错误的。我不知道该怎么做:
foreach (<T> subclasse yadda yadda) {
SyncProductsByType<something?>();
}
那还差得远。谢谢
编辑: 我不认为这是重复的,因为假设我正在尝试在所有 class 类型的类型中调用一个方法。不,我想做的是针对单个方法调用针对所有派生类型的方法。
您可以执行以下操作:
public class Test
{
public static void SyncProductsByType<T>() where T : BaseProduct
{
// this method is a simple wrapper with constraint
SyncProductsByType(typeof(T));
}
public static void SyncProductsByType(Type type)
{
// decide whether this should public, private or internal
if (type.BaseType != typeof(BaseProduct))
throw new ArgumentOutOfRangeException(nameof(type));
// do work
}
}
public abstract class BaseProduct
{
}
public class ApparelProduct : BaseProduct
{
}
您可以找到所有后代 类,然后以这种方式调用泛型方法:
class Program
{
class BaseClass
{
public static void Generic<T>() where T : BaseClass
{
Console.WriteLine(typeof(T).Name);
}
}
class FirstClass : BaseClass
{
}
class SecondClass : BaseClass
{
}
static void Main(string[] args)
{
MethodInfo method = typeof(BaseClass).GetMethod("Generic");
foreach (var item in Assembly.GetExecutingAssembly().GetTypes()
.Where(myType => myType.IsClass && myType.IsSubclassOf(typeof(BaseClass))))
{
MethodInfo generic = method.MakeGenericMethod(item);
generic.Invoke(null, null);
}
}
}
编辑: 稍微优化一下。
我想你要找的是 Type.IsSubclassOf 这个检查一个类型是否是另一个类型的子类。使用所述 Type
对象调用方法的唯一方法是获取通用定义 MethodInfo
,然后使用 MakeGenericMethod
创建一个通用方法,该方法将 T
设置为指定的Type
,例如:
Type parentType = typeof(BaseProduct);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
var genericDefinition = typeof(BaseClass).GetMethod("SyncProductsByType");
foreach (Type type in types)
{
if (type.IsSubclassOf(parentType))
{
genericDefinition.MakeGenericMethod(type).Invoke(instance, null);
}
}