如何将集合中的方法用作其他类的泛型方法

本文关键字:其他 泛型方法 方法 集合 | 更新日期: 2023-09-27 18:05:37

我锁定了一种方法来使用我的函数GetItem作为一些其他类的泛型方法。这些类都是基于CBase的,我在近20个类中使用了GetItem方法。20个类中唯一不同的是类的类型。本例中的类类型为load。

我将使用函数GetItem作为泛型方法,但我没有看到这样做的方法。现在我把这个函数复制到每个类。

我希望有更好的方法。

using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
namespace WindowsFormsGenerics
{
    public class CLoadListe : Collection<CLoad>
    {
        ///<param name="Searchstring"> String nach dem die Lastenliste durchsucht werden soll </param>
        ///<param name="Parameter"> NAME für Lastenname, ALIASNAME oder DESCRIPTION</param>
        public CLoad GetItem(string Searchstring, string Parameter = "NAME")
        {
            if (this.Count == 0) return null;
            if (Searchstring.Length == 0) return null;
            switch (Parameter)   // Parameter auswerten
            {
                case ("NAME"): return this.Where(item => item.Name == Searchstring).FirstOrDefault();
                case ("DESCRIPTION"): return this.Where(item => item.Description == Searchstring).FirstOrDefault();
                default: throw new System.Exception($"Suchparameter {Parameter} nicht vorhanden");
            }
        }
    }
    /// <summary>Basisklasse für alle Elemente </summary>
    public class CBase
    {
        /// <summary> Elementname </summary>
        public string Name { get; set; }
        /// <summary> Beschreibung </summary>
        public string Description { get; set; }
    }
    public class CKnoten : CBase { }
    public class COneNodeElement : CBase
    {
        /// <summary> KnotenOne des Elementes </summary>
        public CKnoten KnotenOne { get; set; }
        /// <summary> Schaltzustand am KnotenOne </summary>
        public bool SwitchOne { get; set; }
    }
    public class CLoad : COneNodeElement { }

}

谢谢史蒂芬

如何将集合中的方法用作其他类的泛型方法

为列表添加一个基类:

public abstract class CListe<T> : Collection<T>
    where T : CBase
{
    public T GetItem(string Searchstring, string Parameter = "NAME")
    {
        // As is...
    }
}

现在LoadListe只是:

public sealed CLoadListe : CListe<CLoad> { }

但是我要强调一些小问题:

  • 在c#中,类通常不以C为前缀,那么应该Liste, Load等。
  • 参数通常为驼峰式。
  • 你不需要字符串参数,当你有enum是什么?
  • 你的类都是非抽象和非密封的。创建不想实例化abstract的类和不想通过继承扩展sealed的类。
  • 您对his.Count == 0searchString.Length == 0的测试是无用的,this.Where()将按照要求执行,没有它们(这可能是微优化的尝试,但它会降低公共路径性能)。你可能想要添加参数检查(例如,如果searchStringnull抛出ArgumentNullException)。
  • 当你有更好的异常类型时,不要抛出一个泛型的Exception。在这种情况下,你可以使用ArgumentException(或InvalidEnumArgumentException,如果你切换到enum)。
  • 考虑到我放弃参数Parameter,你也在执行顺序比较,并不总是你可能期望的或你可能意识到的。如果你真的必须坚持使用字符串,你最好使用String.Equals()StringComparison.InvariantCultureIgnoreCase

应该可以:

public static class CBaseExtensions
{
    ///<param name="Searchstring"> String nach dem die Lastenliste durchsucht werden soll </param>
    ///<param name="Parameter"> NAME für Lastenname, ALIASNAME oder DESCRIPTION</param>
    public static T GetItem<T>(this Collection<T> self, string Searchstring, string Parameter = "NAME") where T : CBase
    {
        if (self.Count == 0) return null;
        if (Searchstring.Length == 0) return null;
        switch (Parameter)   // Parameter auswerten
        {
            case ("NAME"): return self.FirstOrDefault(item => item.Name == Searchstring);
            case ("DESCRIPTION"): return self.FirstOrDefault(item => item.Description == Searchstring);
            default: throw new System.Exception($"Suchparameter {Parameter} nicht vorhanden");
        }
    }
}

你现在可以这样调用它:

var list = new CLoadListe();
var items = list.GetItem("searchstring", "parameter");

您可以编写一个扩展方法

public static class CLoadExtension
{
    public static CLoad GetItem(this Collection<CLoad> coll, string Searchstring, string Parameter = "NAME")
    {
        if (this.Count == 0) return null;
            if (Searchstring.Length == 0) return null;
            switch (Parameter)   // Parameter auswerten
            {
                case ("NAME"): return this.Where(item => item.Name == Searchstring).FirstOrDefault();
                case ("DESCRIPTION"): return this.Where(item => item.Description == Searchstring).FirstOrDefault();
                default: throw new System.Exception($"Suchparameter {Parameter} nicht vorhanden");
            }
    }
}