C# 重载通用列表';s添加扩展方法

C# 重载通用列表';s添加扩展方法,c#,generics,C#,Generics,我想重载泛型列表的Add方法,以便可以使用集合初始化,如: var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } }; var x=新列表{{“1”,“2”},{“1”,“2”}; (其中Tuple是二进制Tuple的简单自定义实现。) 但是,我创建了一个扩展方法,在cs文件中放置了一个using指令,仍然得到“方法'Add'不重载2个参数”错误。 (使用扩展方法)不可能吗 扩展方法代码: names

我想重载泛型列表的Add方法,以便可以使用集合初始化,如:

var x = new List<Tuple<string>> { { "1", "2" }, { "1", "2" } };
var x=新列表{{“1”,“2”},{“1”,“2”};
(其中Tuple是二进制Tuple的简单自定义实现。) 但是,我创建了一个扩展方法,在cs文件中放置了一个using指令,仍然得到“方法'Add'不重载2个参数”错误。
(使用扩展方法)不可能吗

扩展方法代码:

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 });
        }
    }
}
命名空间扩展方法{
公共静态类扩展{
公共静态无效添加(此列表本身,T值1,T值2){
Add(新元组{value1,value2});
}
}
}

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


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

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

附言:你所做的并不是重载,也没有办法重载现有类中的任何内容


更新:看起来我的第一句话应该是:“在C#中,通过扩展方法是不可能的”

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

在幕后,编译器用对扩展的调用替换对扩展方法的任何调用

看起来您正试图让C#像Ruby一样,通过传递一组值来初始化对象数组,或者至少模仿字典初始化的行为。 不幸的是,如果不实际重载列表,就无法做到这一点

集合初始化只是另一种编译器魔法,它试图找到一个Add方法,该方法的参数数量与参数列表中的项目数量相同。否则,您可以定义一个转换操作符来将列表转换为元组类型


为什么不直接使用内置的对象初始化器呢?您只需在C#6.0[0]中编写更多的代码即可。Microsoft允许在集合初始值设定项中使用扩展方法。万岁

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

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

类程序
{
静态void Main(字符串[]参数)
{
var x=新列表{{“1”,“2”},{“1”,“2”};
}
}
公共静态类扩展
{
公共静态无效添加(此列表本身,T1值1,T2值2)
{
self.Add(Tuple.Create(value1,value2));
}
}

[0]

我认为这是不可能的,因为您希望如何使用它以及对象初始化的工作方式不同。尽管有人可能会对此提出建议。此外,我怀疑对象初始值设定项是否能与扩展方法一起工作。有趣的是,这似乎是受支持的,因为存在一个连接问题,如果您希望看到它也添加到C#中,请投票:这不是关于构造函数,而是关于集合初始值设定项,它需要适用的
Add
方法。实际上,它是关于构造函数的,因为必须先创建元组实例,然后才能将其添加到列表中。@Panagiotis,不,它不是关于构造函数的。元组构造函数必须被调用,但它几乎与对象初始值设定项无关。否(大部分)和是。想想编译器在幕后做了什么。首先,它检查您传递的参数是否是Tuple类型的对象。如果不是,它将在集合中搜索Add方法,该方法接受的参数数量与每个值列表中的参数数量相同。如果使用构造函数或对象初始值设定项,编译器不会尝试查找Add方法。嗯……我正在尝试将方法添加到已经有同名方法但参数不同的类型。如果这不是重载,那是什么?我之所以这么说是因为扩展方法并没有真正添加到类型中。您可以调用它们,使其看起来像是类型的一部分,但它们仍然不是类型的一部分/更新^2:看起来你的第一句话应该是:“在6.0版之前的C#中,通过扩展方法是不可能的”:D“你为什么不直接使用内置的对象初始值设定项?你只需要再编写一点代码就可以了”。但是我首先使用初始值设定项来减少代码膨胀…
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 ));
    }
}