Con*_*tor 10 c# collections emplace
从C++ 11开始,人们可以写出类似的内容
#include <vector>
#include <string>
struct S
{
S(int x, const std::string& s)
: x(x)
, s(s)
{
}
int x;
std::string s;
};
// ...
std::vector<S> v;
// add new object to the vector v
// only parameters of added object's constructor are passed to the function
v.emplace_back(1, "t");
Run Code Online (Sandbox Code Playgroud)
是否有的C++函数任何C#类似物像emplace或emplace_back容器类(System.Collections.Generic.List)?
更新:
在C#中,类似的代码可能会被编写为list.EmplaceBack(1, "t");代替list.Add(new S(1, "t"));.不记得班级名称并且new ClassName每次都在这种情况下写作会很好.
一般来说,C#中没有任何类似的东西,它的需求远远低于C++.
在C#中,当你拥有一个List<SomeReferenceType>你真正拥有的是一个List<ReferenceToSomeType>引用列表时,每个元素的大小为4或8个字节(请参阅.NET中的对象引用有多大?).复制引用不会导致底层对象被复制,因此它非常快(您正在复制大约4或8个字节,并且处理器已针对此操作进行了优化,因为这是处理器的本机指针的大小).所以,当你someList.Add(someReference)正在做的是添加对你的引用List<>.
在C++中,当你拥有的std::vector<SomeType>是一个向量时SomeType,每个元素的大小等于sizeof(SomeType).插入新元素std::vector<>将导致您插入的元素被复制(克隆,复制...选择您喜欢的动词).这是一项昂贵的操作.
您使用的模式通常是您创建一个对象只是为了将其插入到std::vector<>.为了在C++ 11中优化此操作,他们添加了两种方法:移动语义的std::vector<>::emplace方法和支持std::vector<>.不同之处在于移动语义必须由SomeType类型支持(您需要带有说明noexcept符的移动构造函数),而每种类型都支持emplace(最终只使用了放置构造函数).
您可以通过扩展稍微改进@Boo 变体。您可以使用Activator.CreateInstance
创建对象实例,从而使解决方案更加通用。
public static class ListExtension
{
public static void Emplace<S>(this IList<S> list, params object[] parameters)
{
list.Add((S)Activator.CreateInstance(typeof(S), parameters));
}
}
Run Code Online (Sandbox Code Playgroud)
注意:没有检查类型和计数参数,所以如果你做错了什么,你只会在运行时得到错误