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

发布于 2024-09-11 13:51:04 字数 688 浏览 3 评论 0原文

我有一个辅助类,它对实体列表执行简单但重复的过程。为了简单起见,就像这样...

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

我现在需要添加对另一种类型的支持,但一切都是相同的...我如何避免像这样的重载方法列表不断增加:

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

...等等。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狠疯拽 2024-09-18 13:51:04

这里有两种方法:

  1. 使用泛型和公共基类
  2. 使用接口

方法 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();
    }
}

方法 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();
    }
}

现在,如果您尝试使该方法直接使用接口,如下所示:

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

那么如果您有一个 ListList,那么这将起作用。 ICommon> 当您调用它时,但如果您有 List,则不起作用。在 C# 4.0 中,如果我们稍微更改一下方法就可以完成此操作:

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

请注意,我改为使用 IEnumerable。这里的概念称为协方差和逆变,除此之外我不会对此进行太多介绍。搜索 Stack Overflow 以获取有关该主题的更多信息。

提示:无论如何,我都会将输入参数更改为 IEnumerable,因为这将使您的方法在更多实例中可用,您可以拥有不同类型的集合、数组等等,只要它们包含正确的类型,它们就可以传递给该方法。通过将自己限制为 List,您可以在某些情况下强制代码的用户转换为列表。我的指导方针是输入参数尽可能不具体,输出参数尽可能具体。

Here's two ways:

  1. Use generics, and a common base class
  2. Use interfaces

Method 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:

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>. In C# 4.0 this can be done if we change the method slightly:

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. 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. By limiting yourself to List<T> you force the user of your code to convert to a list in some cases. My guidelines are to be as unspecific as possible in input parameters, and as specific as possible in output parameters.

画中仙 2024-09-18 13:51:04

假设每个列表类型的属性具有相同的名称和类型,您可以添加一个包含该属性的接口,并为要调用此方法的每个类型实现它:

public interface ISomeProperty
{
    object SomeProperty { get; }
}

DoSomethingSimple 可以是:

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

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:

public static List<T> DoSomethingSimple<T>(IEnumerable<T> list) where T : ISomeProperty
{
    return list.Where(i => i.SomeProperty.Equals(2)).ToList();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文