【问题标题】:How can I use an method from a collection as an generic method for other classes如何将集合中的方法用作其他类的通用方法
【发布时间】:2016-09-05 12:27:37
【问题描述】:

我正在锁定一种将我的函数 GetItem 用作其他一些类的泛型方法的方法。这些类都是基于 CBase 的,我使用 GetItem 方法分成了近 20 个类。 20 个类的唯一区别是类类型。在这个例子中是类类型 CLoad。

我会使用函数 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 { }


}

谢谢 史蒂芬

【问题讨论】:

  • 看接口

标签: c# generics collections


【解决方案1】:

为您的列表添加一个基类:

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

【讨论】:

  • 谢谢,可以了 :)
【解决方案2】:

这应该可行:

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");

【讨论】:

    【解决方案3】:

    你可以写一个扩展方法

    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");
                }
        }
    }
    

    【讨论】:

    • 我写上一篇文章的时候还没有!
    猜你喜欢
    • 2011-03-08
    • 2013-12-26
    • 2017-06-25
    • 2013-01-23
    • 2016-10-05
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多