Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C# 4's covariance support nesting of generics?

I don't understand why 'x' below converts, but 'y' and 'z' do not.

var list = new List<List<int>>();

IEnumerable<List<int>> x = list;
List<IEnumerable<int>> y = list;
IEnumerable<IEnumerable<int>> z = list;

Does the new covariance feature simply not work on generics of generics or am I doing something wrong? (I'd like to avoid using .Cast<> to make y and z work.)

like image 721
scobi Avatar asked Apr 21 '10 16:04

scobi


People also ask

What is the main cause of hep C?

Hepatitis C is a liver infection caused by the hepatitis C virus (HCV). Hepatitis C is spread through contact with blood from an infected person. Today, most people become infected with the hepatitis C virus by sharing needles or other equipment used to prepare and inject drugs.

Does hep C go away?

Hepatitis C virus (HCV) causes both acute and chronic infection. Acute HCV infections are usually asymptomatic and most do not lead to a life-threatening disease. Around 30% (15–45%) of infected persons spontaneously clear the virus within 6 months of infection without any treatment.

What does hep C pain feel like?

Many people with chronic HCV suffer from aches and pains in their joints. A variety of different joints can be involved but the most common are in the hands and wrists. These pains are often minor but occasionally the pain can be quite severe. In such cases painkillers can be used to relieve the symptoms.

How long can you have hep C without knowing?

Today, chronic HCV is usually curable with oral medications taken every day for two to six months. Still, about half of people with HCV don't know they're infected, mainly because they have no symptoms, which can take decades to appear.


2 Answers

"z" is fine in C# 4.0, IEnumerable<T> is covariant. List<T> is however not, you cannot make "y" work.

Intuitively, if it were then this would be valid:

List<IEnumerable<int>> y = list
y.Add(new Stack<int>());

Which breaks the promise that "list" can only contain List<int> elements.

like image 173
Hans Passant Avatar answered Nov 08 '22 10:11

Hans Passant


You are making several mistakes here. First, covariance and contravariance are not supported for value types, so whatever you try to do with "int" wouldn't work.

Second, the valid example checking for variance in nested generic types looks more like this:

var list = new List<List<String>>();
IEnumerable<IEnumerable<object>> z = list; 

I can assign List of List of strings to IEnumerable of IEnumerables of objects, which is covariance. For more info, check out Covariance and Contravariance FAQ.

like image 34
Alexandra Rusina Avatar answered Nov 08 '22 09:11

Alexandra Rusina