Starting in C++11, one can write something like
#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");
Is there any C# analogue of C++ functions like emplace
or emplace_back
for container classes (System.Collections.Generic.List
)?
Update:
In C# similar code might be written as list.EmplaceBack(1, "t");
instead of list.Add(new S(1, "t"));
. It would be nice not to remember a class name and write new ClassName
in such situations every time.
C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
C+ does exist. My mother used it in university in preC++ days. C# or C sharp is a programming language that is an improvement of the original C language C is a language commonly used for creating basic OS C+, or Holy C, is a language created by the schizophrenic Terry A.
C is one of the earliest and most widely used programming languages. C is the fourth most popular programming language in the world as of January 2022. Modern languages such as Go, Swift, Scala, and Python are not as popular as C. Where is C used today?
So, there were standards before and after ANSI C. Let's continue with a discussion of all the five different standards of C — K&R C, ANSI C, C99, C11 and Embedded C. For the purposes of our discussion, the compiler used is the gcc C compiler from the GNU Compiler Collection (GCC).
In general there is nothing similar in C#, and its need is much less than in C++.
In C# when you have a List<SomeReferenceType>
what you really have is a List<ReferenceToSomeType>
, so a list of references, with the size of each element of 4 or 8 bytes (see How big is an object reference in .NET?). Copying a reference doesn't cause the underlying object to be duplicated, so it is very fast (you are copying around 4 or 8 bytes, and the processor is optimized for this operation, because that is the size of the native pointer of the processor). So when you someList.Add(someReference)
what you are doing is adding a reference to your List<>
.
In C++ when you have a std::vector<SomeType>
what you have is a vector of SomeType
, with the size of each element equal to sizeof(SomeType)
. Inserting a new element in std::vector<>
will cause the element you are inserting to be duplicated (cloned, copied... choose a verb you like). This is an expensive operation.
Quite often the pattern you use is that you create an object just to insert it into a std::vector<>
. To optimize this operation in C++11 they added two ways to do it: the std::vector<>::emplace
method and support by the std::vector<>
of the move semantic. The difference is that the move semantic must be supported by the SomeType
type (you need a move constructor with the noexcept
specifier), while every type supports the emplace
(that in the end simply used placement constructor).
You can a bit improve @Boo variant with extenstion.
You can create object instance with Activator.CreateInstance so it make solution more generic.
public static class ListExtension
{
public static void Emplace<S>(this IList<S> list, params object[] parameters)
{
list.Add((S)Activator.CreateInstance(typeof(S), parameters));
}
}
Note: not checked type and count parameters, so if you do something wrong, you get errors just in run-time
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With