I'm trying to build a list of generic items using the out generic modifier but I'm getting the error 'Invalid variance: The type parameter 'T' must be invariantly valid on 'ITestInterface.Value'. 'T' is covariant.'
I'm also getting an error trying to store value types as well as reference types.
I'd like a list of generic objects, each with different type T, and use type T in the interface.
Could someone tell me what I'm doing wrong?
public MainWindow()
{
var list = new List<ITestInterface<object>>();
list.Add(new Test<string>());
list.Add(new Test<int>());
foreach (var item in list)
{
var x = item.Value;
}
}
public interface ITestInterface<out T>
{
T Value { get; set; }
}
public class Test<T> : ITestInterface<T>
{
public T Value { get; set; }
}
I've been working from https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-generic-modifier and Collection of derived classes that have generic base class.
Thanks for anyone's help!
Update:
Thank you to everyone who has helped me understand this area a bit more. I see now that I misunderstood the usage of the out/in generic modifier. The question and answers in Invalid variance: The type parameter 'T' must be contravariantly valid on 'UserQuery.IItem<T>.ItemList'. 'T' is covariant is definitely related to most of what I was trying to do, but I was also trying to add reference and value types as type parameters.
One (slightly dubious) work around that I found is to remove the generics from the class and use them instead in a static method that returns an instance of the class. Definitely not type safe, but it does allow reference and value types to be used:
public MainWindow()
{
var list = new List<Test>();
list.Add(Test.Create<string>("test"));
list.Add(Test.Create<int>(5));
foreach (var item in list)
{
var x = item.Value;
}
}
public class Test
{
public object Value { get; set; }
public Type ValueType { get; set; }
public static Test Create<T>(T value)
{
return new Test
{
Value = value,
ValueType = typeof(T),
};
}
public T GetValue<T>()
{
if (typeof(T) == ValueType)
return (T)Convert.ChangeType(Value, typeof(T));
else
throw new InvalidOperationException();
}
}