如何在泛型方法中过滤集合

vmb*_*vmb 0 .net c# generics generic-collections

我有两个类,它具有以下属性

 Class A
  {
      public int CustID { get; set; }
      public bool isProcessed { get; set; }
  }
  Class B
  {
      public int EmpId{ get; set; }
      public bool isProcessed { get; set; }
  }
Run Code Online (Sandbox Code Playgroud)

我创建了一个接受所有这些类的泛型方法.'isProcessed'属性在这两个类中都很常见.

public void ProceesData<T>(IList<T> param1, string date1)
{

}
Run Code Online (Sandbox Code Playgroud)

我需要关注的事情

  1. 在ProcessData方法内部我想过滤具有isProcessed标志的项目为"True".
  2. 此外,我想迭代此集合,并需要为IsProcessed属性设置值.

注意:我更喜欢使用反射的解决方案,因为属性名称是常量(即"IsProcessed")

任何人都可以帮助这个.

Dav*_*idG 6

最简单的方法是确保两个类都实现一个公共接口并约束您的泛型方法.例如:

public interface IProcessable
{
    bool isProcessed { get; set; }
}
public class A : IProcessable
{
    public int CustID { get; set; }
    public bool isProcessed { get; set; }
}

public class B : IProcessable
{
    public int EmpId { get; set; }
    public bool isProcessed { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在你的方法看起来像这样:

public void ProceesData<T>(IList<T> param1, string date1)
    where T : IProcessable // <-- generic constraint added
{
    foreach (var element in param1)
    {
        element.isProcessed = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不能使用接口或属性名称变得更有用的另一个选项是Action<T>将参数作为参数传递给您的方法.例如:

public void ProceesData<T>(IList<T> param1, string date1, Action<T> func)
{
    foreach (var element in param1)
    {
        func(element);
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

ProceesData<A>(list, "", x => x.isProcessed = true);
Run Code Online (Sandbox Code Playgroud)

  • @vmb反射是非常笨重和缓慢的,我不会建议 (4认同)
  • @GabrielNegut:不,`IList <T>`不是协变的(它是`IList <T>`不是`IList <out T>`).这意味着您可以使用IList <A>,IList <B>或IList <IProcessable>调用泛型方法,但只有后者可以"转换"为IList <IProcessable>.如果你可以使用`IEnumerable <out T>`而不是`IList`,那么非泛型方法可以正常工作. (3认同)
  • @vmb但是*为什么*?第二个选项将为您完成工作. (2认同)