目前我有此方法
public void HandleComponent<T>() where T : IComponent
{
// do something with T
}
我想拥有一个方法HandleComponents
,在其中我可以传递多个泛型类型,并且该方法遍历它们并调用HandleComponent<currentGenericType>
。
我知道不可能有可变数量的通用参数,但是如何为该问题创建解决方法?我开始创建这个
public void HandleComponents(Type[] components)
{
for (int i = 0; i < components.Length; i++)
{
HandleComponent<components[i]>(); // This is not possible
}
}
components[i]
需要进行转换,因为当前这不是通用参数
我必须确保每个Type
参数都实现IComponent
。我知道我可以在方法中进行检查,但是我想防止传入无效的参数。因此该方法必须看起来像(伪代码)
public void HandleComponents(Type[] components) where components : IComponent
{
for (int i = 0; i < components.Length; i++)
{
HandleComponent<components[i]>();
}
}
这是不可能的,对吧?
完美的解决方案看起来像这样
public void HandleComponents<AListOfGenericTypes>() where EachGenericListItem : IComponent
{
for (int i = 0; i < AListOfGenericTypes.Count; i++)
{
HandleComponent<AListOfGenericTypes[i]>();
}
}
答案 0 :(得分:1)
如何使用params:
class Program
{
static void Main(string[] args)
{
IComponent cp1 = new Component1();//Created here or elsewhere
IComponent cp2 = new Component2();//Created here or elsewhere
IComponent cp3 = new Component3();//Created here or elsewhere
HandleComponents<IComponent>(cp1, cp2, cp3);
}
private static void HandleComponents<T>(params T[] components) where T : IComponent
{
foreach (T component in components)
{
HandleComponent(component);
}
}
private static void HandleComponent<T>(T component) where T : IComponent
{
//Do whatever with T
}
}
public class Component1 : IComponent { }
public class Component2 : IComponent { }
public class Component3 : IComponent { }
public interface IComponent { }
答案 1 :(得分:1)
没有反思就不可能。我建议您重写方法HandleComponent
:
public void HandleComponent(Type objectType)
{
// do something with T
}
您可以致电:
public void HandleComponents(Type[] components)
{
for (int i = 0; i < components.Length; i++)
{
HandleComponent(components[i]);
}
}
反射解决方案:
public void HandleComponents(Type[] components)
{
var method = this.GetType().GetMethod("HandleComponent");
for (int i = 0; i < components.Length; i++)
{
method.MakeGenericMethod(components[i])
.Invoke(this, null);
}
}
答案 2 :(得分:1)
如果您想这样做,并且可以接受可以传递的实际组件数量上限,请从const currentUrl = this.location.path();
const displayTile = currentUrl.includes('/search-resources') || currentUrl.includes('/calendar') || currentUrl.includes('/yearbooks')? 1 : 2;
,{{1} }和Func
系列类型,并让您的复制和粘贴手指热身:
Action
这是不理想的,而且就像我说的那样,它对一个调用可以传递多少个组件施加了上限。因为每个调用都必须分别进行参数设置,所以这里无法使用循环。
或者:
Tuple
这里是text template,可减少复制和粘贴(并更可重用于其他方法):
将public void HandleComponent<T>(T component) where T : IComponent
{
//Real logic
}
public void HandleComponents<T1, T2>(T1 component1, T2 component2)
where T1 : IComponent
where T2 : IComponent
{
HandleComponent(component1);
HandleComponent(component2);
}
public void HandleComponents<T1, T2, T3>(T1 component1, T2 component2, T3 component3)
where T1 : IComponent
where T2 : IComponent
where T3 : IComponent
{
HandleComponent(component1);
HandleComponent(component2);
HandleComponent(component3);
}
作为文本模板添加到您的项目中,然后为其提供以下内容:
public void HandleComponent<T>() where T : IComponent
{
//Real logic
}
public void HandleComponents<T1, T2>()
where T1 : IComponent
where T2 : IComponent
{
HandleComponent<T1>();
HandleComponent<T2>();
}
public void HandleComponents<T1, T2, T3>()
where T1 : IComponent
where T2 : IComponent
where T3 : IComponent
{
HandleComponent<T1>();
HandleComponent<T2>();
HandleComponent<T3>();
}
(您将要针对这些方法应进入的类编辑第8行,并确保在其他位置将其标记为局部。也请针对名称空间进行调整)
答案 3 :(得分:1)
我认为不可能完全实现您想要的目标,但是您可以通过使用反射和MakeGenericMethod来获取通用的HandleComponent方法并使用传递给HandleComponents方法的类型来调用它来克服这个问题,只是传入类型的过滤必须在for循环中进行,而不必通过通用约束,因为该方法没有通用的方法。
class Program
{
public interface IComponent { }
public class ComponentA : IComponent { }
public class ComponentB : IComponent { }
static void Main(string[] args)
{
HandleComponents(new[] { typeof(ComponentB), typeof(ComponentA) });
Console.ReadKey();
}
private static void HandleComponent<T>()
where T : IComponent
{
Console.WriteLine(typeof(T));
}
private static void HandleComponents(Type[] components)
{
var m = typeof(Program).GetMethod("HandleComponent", BindingFlags.NonPublic | BindingFlags.Static);
foreach (var component in components)
{
if (typeof(IComponent).IsAssignableFrom(component))
{
var genericMethod = m.MakeGenericMethod(component);
genericMethod.Invoke(null, null);
}
}
}
}