I have a specialized generic collection class which will be used to hold collections of many different types of objects. Once the collection is created, I need to instantiate the collection's items. I am having the darnedest time getting this to work. There must be a simple solution I am missing.
Here is a sample class which kind of illustrates what I am trying to do and the warnings/errors I am bumping up against.
// Note: T may either a string or other reference type that supports IEnumerable.
public class Foo<T>
{
private List<T> fooBarList = new List<T>();
public Foo()
{
Bar1<T>();
Bar2<T>();
Bar3<T>();
}
public void Bar1<T>()
{
// Error Message: Argument 1 cannot convert from 'T...' to 'T...'
T t = default;
fooBarList.Add(t);
}
public void Bar2<T>() where T : IEnumerable, new()
{
// Error Message: T must be a non-abstract type with public
// parameterless constructor in order to use it as a parameter 'T'
// in the generic type or method 'Foo<T>.Bar2<T>()
fooBarList.Add(new T());
}
public void Bar3<T>() where T : IEnumerable, new()
{
// Error Message: Argument 1 cannot convert from 'T...' to 'T...'
T t = Activator.CreateInstance<T>();
fooBarList.Add(t);
}
}
Side note: This particular code is in a particularly performance-critical part of my application--you know, the 3% Donald Knuth talks about needing to actually be optimized. This really does need to be fast because it will get called millions of times per application execution. I would not be at all enthusiastic about using reflection (e.g. Activator.CreateInstance() here) if there is any other alternative. (For now, even that does not seem to be working for me.) I would much rather have the compiler resolve the data type at compile time.
This question was already answered in the link below, but none of the approaches seem to be working for me. What am I missing?
In C#, how to instantiate a passed generic type inside a method?
FYI, I am using .NET Core 2.2 Beta and .NET Standard 2.0 on a Windows 10 machine running Visual Studio 2019 Enterprise Preview.
public void Bar1<T>()... should bepublic void Bar1(), these methods should not be generic but rather use the classe's generic type<T>bits at the function level.where T : new(), so that means you can safely dovar myT = new T();Just make sure you add that constraint wherever you need it. You can defineTat the class level (and include the constraint there) if you want it to be the same everywhere.