【问题标题】:How to pass search parameter, into function that will search a c# collection如何将搜索参数传递给将搜索 C# 集合的函数
【发布时间】:2020-06-01 01:28:14
【问题描述】:

假设我有一个表单集合:

List<Member> myMembers= new List<Member>() 
{ 
    new Member(){ID=1,FirstName="John",LastName="Doe"}, 
    new Member(){ID=3,FirstName="Allan",LastName="Jones"}, 
    new Member(){ID=2,FirstName="Martin",LastName="Moe"}, 
    new Member(){ID=4,FirstName="Ludwig",LastName="Issac"} 
};

我可以通过 FirstName 对这个列表进行排序,方法是:

myMembers.Sort((x, y) => x.FirstName.CompareTo(y.FirstName)); 

我想在函数内部执行此操作,以便可以传递所需的搜索参数。比如:

public void sortCollection( parameter SearchTerm, List<Member> myCollection )
{
    myCollection ((x, y) => x.SearchTerm.CompareTo(y.FirstName)); 
}

显然在这里,我无法通过这种方式传递所需的搜索字段,但是可以按照我的要求进行操作吗?

【问题讨论】:

  • 您可以传递一个函数Func&lt;T&gt;,它将包含所需的属性
  • 我不会为这样做的方法而烦恼。只需按原样使用IEnumerable.OrderBy 或Sort。并研究更大的鱼
  • 不要认为你可以在没有反射或其他魔法的情况下推断出这样的属性。但是有一个问题,在这个例子中,你为什么要为基本的内置类型(如 String)使用排序谓词?
  • 请分享一个你正在尝试做的例子。
  • 为什么要将排序作为具有通用搜索词的功能。 C# linq 已经为我们提供了 Linq OrderBy() 和 Sort() 方法,您可以在其中根据您的要求传递谓词。就像myMembers.Sort(x =&gt; x.Id); 或myMembers.Sort(x =&gt; x.FirstName); 或myMembers.Sort(x =&gt; x.LastName); 我相信你只是在重新发明轮子。如果我在这里错了,请纠正我

标签: c# list linq sorting collections


【解决方案1】:

Demo on dotnet fiddle

在我看来,您可以使用 Func 来进行动态排序。

var result = sortCollection(p => p.ID, myMembers);

public static IEnumerable<Member> sortCollection(Func<Member, object> keySelector, List<Member> myCollection)
{
    return myCollection.OrderBy(keySelector);
}

阅读以下文章以更好地理解

Dynamic Order By in Linq

【讨论】:

  • 这除了创建更多的 CIL 并让用户输入更多的文本来实现同样的事情之外什么也没做
【解决方案2】:

不要在 Linq .OrderBy() 或 .Sort() 方法上再编写一个包装器并在您想要排序的任何地方调用它,而是使用 Linq OrderBy() 或 .Sort() 方法

用Sort()点赞

//If you want to sort collection by Id then
myMembers.Sort(x => x.Id); 

//If you want to sort collection by FirstName then
myMembers.Sort(x => x.FirstName);

...

要在 OrderBy()/Sort() 之间做出决定,请阅读下面的问答帖

C# Sort and OrderBy comparison

【讨论】:

    【解决方案3】:

    为什么不简单地使用内置函数?

    myMembers.OrderBy(m => m.FirstName)
    

    如果您真的愿意,您可以围绕此函数编写自己的包装器,但调用看起来或多或少相同,并且有点重新发明轮子。

    类似这种扩展方法:

    public static IEnumerable<T> OrderByWrapper<T, TKey>(this IEnumerable<T> source, Func<T,TKey> keySelector)
    {
        return source.OrderBy(keySelector);
    }
    

    你可以这样称呼它:

    myMembers.OrderByWrapper(m => m.FirstName)
    

    【讨论】:

      【解决方案4】:

      您可以为此创建一个通用扩展方法并将Func&lt;T, TResult&gt;委托传递给它,它用作内置Sort方法的键选择器

      public static void SortExt<T, TValue>(this List<T> collection, Func<T, TValue> selector)
      {
          var comparer = Comparer<TValue>.Default;
          collection.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
      }
      

      请记住,您应该比较比较对象的相同字段。

      使用示例

      myMembers.SortExt(member => member.FirstName);
      

      如果只想比较myMembers集合,可以简化声明

      public static void SortExt<TValue>(this List<Member> members, Func<Member, TValue> selector)
      {
          var comparer = Comparer<TValue>.Default;
          members.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
      }
      

      另一种选择是引入Comparison&lt;T&gt;委托实例来存储字段比较的逻辑并将其传递给Sort方法。您可以在此处指定所需的任何自定义比较

      Comparison<Member> comparison = (x, y) => x.FirstName.CompareTo(y.FirstName);
      myMembers.Sort(comparison);
      

      【讨论】:

      • @pelt 它回答了你的问题吗?您需要更多信息或详细信息吗?
      猜你喜欢
      • 2019-11-11
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      相关资源
      最近更新 更多