重载通用List的Add with extension方法

时间:2011-03-28 10:43:26

标签: c# generics

我想重载一个通用列表的Add方法,所以我可以使用集合初始化,如:

var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } };

(其中Tuple是二进制元组的简单自定义实现。) 但是,我创建了一个扩展方法,在cs文件中放置了一个using指令,并且仍然得到“方法无过载'添加'需要2个参数”-error。 是不是可以做(用扩展方法)?

扩展方法代码:

namespace ExtensionMethods {
    public static class Extensions{
        public static void Add<T>(this List<Tuple<T>> self, T value1, T value2) {
            self.Add(new Tuple<T> { value1, value2 });
        }
    }
}

4 个答案:

答案 0 :(得分:2)

通过扩展方法无法实现。为了使这种语法有效,您必须创建自己的集合类,该集合类将具有void Add(T value1, T value2)签名。

P.S。:你所做的不是overload而且没有办法在现有的课程中重载任何东西。

更新:看起来我的第一句应该是:“通过C#中的扩展方法无法实现”

答案 1 :(得分:1)

您无法使用扩展方法实现构造函数.Extension方法只不过是一个接受对象实例的静态方法。因此,您需要首先有一个实例才能传递给它。

但您可以使用列表的AddRange()来初始化您的列表。

答案 2 :(得分:1)

在C#6.0 [0]中,Microsoft允许在集合初始值设定项中使用扩展方法。欢呼:)

由于这不是.NET Framework或CLR的更改,而是编译器的更改,因此该功能可以与.NET 4.0一起使用。

以下是现在有效的C#代码。 (在Visual Studio 2015 RC中测试)

class Program
{
    static void Main(string[] args)
    {
        var x = new List<Tuple<string,string>> { { "1", "2" }, { "1", "2" } };
    }
}
public static class Extensions
{
    public static void Add<T1,T2>(this List<Tuple<T1,T2>> self, T1 value1, T2 value2)
    {
        self.Add(Tuple.Create( value1, value2 ));
    }
}

C# 6 Features [0]

答案 3 :(得分:0)

扩展方法不能仅仅因为它们不是目标类型的成员而重载在其目标类型上定义的任何方法。扩展方法不会向目标类型添加任何内容。它们只是编译器魔术,允许它们被调用,就像它们是在其目标类型上定义的方法一样。实际上,它们是在一个单独的静态类型中定义的,因此它们不能在目标类型上重载任何方法。

在幕后,编译器通过调用Extensions来替换对您的扩展方法的任何调用。

看起来您正在尝试使C#像Ruby一样运行并通过传递一组值来初始化对象数组,或者至少模仿字典初始化的行为。 不幸的是,如果没有实际重载List&lt;&gt;,就无法做到这一点。

集合初始化只是编译器魔法的另一部分,它试图找到一个参数列表中有项目的参数一样多的Add方法。如果是这样,你可以定义一个转换运算符来将列表转换为你的元组类型。

为什么不直接使用内置对象初始值设定项?你只需要编写更多的代码