简体   繁体   English

一系列重载方法的替代方法

[英]Alternative To A Series Of Overloaded Methods

I have a helper class that does a simple but repetitive process on a List of entities. 我有一个帮助程序类,它对实体列表执行简单但重复的过程。 For simplicity, it's like this... 为了简单起见,就像这样...

public static List<MyType> DoSomethingSimple(List<MyType> myTypes) {
    return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
}

I now need to add support for another type, but everything is identical... how do I avoid an increasing list of overloaded methods like this: 现在,我需要添加对另一种类型的支持,但是所有内容都是相同的……如何避免增加这样的重载方法列表:

public static List<MyType> DoSomethingSimple(List<MyType> myTypes) {
    return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
}

public static List<MyOtherType> DoSomethingSimple(List<MyOtherType> myOtherTypes) {
    return myOtherTypes.Where(myOtherType => myOtherType.SomeProperty.Equals(2)).ToList();
}

... and so on. ... 等等。

Here's two ways: 这有两种方式:

  1. Use generics, and a common base class 使用泛型和通用基类
  2. Use interfaces 使用界面

Method 1: 方法1:

public class BaseClass
{
    public int SomeProperty { get; set; }
}

public class MyType : BaseClass { }
public class MyOtherType : BaseClass { }

public class ClassWithMethod
{
    public static List<T> DoSomethingSimple<T>(List<T> myTypes)
        where T : BaseClass
    {
        return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
    }
}

Method 2: 方法2:

public interface ICommon
{
    int SomeProperty { get; set; }
}

public class MyType : ICommon
{
    public int SomeProperty { get; set; }
}

public class MyOtherType : ICommon
{
    public int SomeProperty { get; set; }
}

public class ClassWithMethod
{
    public static List<T> DoSomethingSimple<T>(List<T> myTypes)
        where T : ICommon
    {
        return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
    }
}

Now, if you try to make the method use the interface directly, like this: 现在,如果您尝试使方法直接使用接口,如下所示:

public class ClassWithMethod
{
    public static List<ICommon> DoSomethingSimple(List<ICommon> myTypes)
    {
        return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
    }
}

Then that would work if you have a List<ICommon> when you call it, but won't work if you have a List<MyType> . 然后,如果您在调用List<ICommon>时可以使用,但如果使用List<MyType>则无法使用。 In C# 4.0 this can be done if we change the method slightly: 在C#4.0中,如果我们稍微改变一下方法就可以做到:

public class ClassWithMethod
{
    public static List<ICommon> DoSomethingSimple(IEnumerable<ICommon> myTypes)
    {
        return myTypes.Where(myType => myType.SomeProperty.Equals(2)).ToList();
    }
}

Note that I changed to using an IEnumerable<ICommon> instead. 请注意,我改为改为使用IEnumerable<ICommon> The concept here is called Co- and contra-variance, and beyond that I'm not going to say much about it. 这里的概念称为协方差和反方差,除此之外,我将不多说。 Search Stack Overflow for more information on the subject. 搜索堆栈溢出以获取有关该主题的更多信息。

Tip : I would change the input parameter to be IEnumerable<T> regardless, since this would make your method usable in more instances, you could have different types of collections, arrays, etc. and as long as they contain the right type, they can be passed to the method. 提示 :无论如何,我都会将输入参数更改为IEnumerable<T> ,因为这将使您的方法可在更多实例中使用,因此您可以具有不同类型的集合,数组等,只要它们包含正确的类型,它们可以传递给该方法。 By limiting yourself to List<T> you force the user of your code to convert to a list in some cases. 通过将自己限制为List<T> ,在某些情况下,您迫使代码的用户转换为列表。 My guidelines are to be as unspecific as possible in input parameters, and as specific as possible in output parameters. 我的准则是在输入参数中尽可能不具体,在输出参数中尽可能不具体。

Assuming the property has the same name and type for each list type, you could add an interface containing the property and implement it for each type you want to call this method on: 假设每种列表类型的属性名称和类型都相同,则可以添加一个包含该属性的接口,并针对要在其上调用此方法的每种类型实现该接口:

public interface ISomeProperty
{
    object SomeProperty { get; }
}

DoSomethingSimple could then be: 然后, DoSomethingSimple可以是:

public static List<T> DoSomethingSimple<T>(IEnumerable<T> list) where T : ISomeProperty
{
    return list.Where(i => i.SomeProperty.Equals(2)).ToList();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM