代码之家  ›  专栏  ›  技术社区  ›  Fenton

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

  •  1
  • Fenton  · 技术社区  · 16 年前

    我有一个助手类,它在一个实体列表上执行一个简单但重复的过程。简单来说,就是这样…

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

    …等等。

    2 回复  |  直到 16 年前
        1
  •  4
  •   Lasse V. Karlsen    16 年前

    有两种方法:

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

    如果你有一个 List<ICommon> 当你打电话的时候,但是如果你有一个 List<MyType> . 在C 4.0中,如果我们稍微改变方法,就可以做到这一点:

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

    注意,我改为使用 IEnumerable<ICommon> 相反。这里的概念被称为协变和逆变,除此之外,我不想多说。有关主题的详细信息,请搜索堆栈溢出。

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

        2
  •  2
  •   Lee    16 年前

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

    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();
    }
    
    推荐文章