Reputation: 5135
Consider the code:
using System.Collections.Generic;
namespace TestingTypes
{
class Program
{
static void Main(string[] args)
{
var strings = new List<string>();
INeedToPassThisMethodAListOfObjects(strings as List<object>);
}
static void INeedToPassThisMethodAListOfObjects(List<object> objects) { }
}
}
1>------ Build started: Project: TestingTypes, Configuration: Debug Any CPU ------
1>c:\users\[censored]\TestingTypes\Program.cs(9,41,9,64): error CS0039: Cannot convert
type 'System.Collections.Generic.List<string>' to
'System.Collections.Generic.List<object>' via a reference conversion, boxing
conversion, unboxing conversion, wrapping conversion, or null type conversion
You might say that a List<string> is a List<object>, since a string is an object and C# 4 is supposed to support covariance in generic types.
Upvotes: 2
Views: 1483
Reputation: 2929
You have to convert the strings to objects. Theres a nice LINQ method to do so.
var strings = new List<string>();
INeedToPassThisMethodAListOfObjects(strings.Cast<object>());
Edit
According to your own link,
In C#, variance is supported in the following scenarios:
Covariance in arrays (since C# 1.0)
Covariance and contravariance in delegates, also known as “method group variance” (since C# 2.0)
Variance for generic type parameters in interfaces and delegates (since C# 4.0)
So IEnumerable would accept List
Upvotes: 2
Reputation: 245419
You're getting the error because a List<string>
is not a List<object>
.
You can call list.Add(new TextBox())
on List<object>
but, obviously, the same call doesn't work on List<string>
.
C# Generics only allow for Covariance if the generic type is immutable (which is my the cast from List to IEnumerable works).
If you need to pass the list to a method, you could try passing
listOfStrings.Cast<object>();
On the downside, if you use that solution, any modifications made to the list inside the method call will not be reflected in the original list (because the call to Cast
creates a new list).
If you have control of the method INeedToPassThisMethodAListOfObjects
and that method only needs to iterate over the collection rather than modify it, you can change the parameter type to be IEnumerable<object>
in which case you'd simply be able to pass your List<string>
without any issues.
Upvotes: 3
Reputation: 21713
Interfaces can be variant; classes cannot. See here for the explanation.
Your code will work if you pass the strings
collection uncasted and change the declaration to be
static void INeedToPassThisMethodAListOfObjects(IEnumerable<object> objects) { }
However, that depends on whether you need a List
within this function.
Upvotes: 3