4
What is the difference between Generics statements when using out
and in
?
Example:
public class GenericClass<T> { }
public class GenericClassOut<out T> { }
public class GenericClassIn<T in> { }
4
What is the difference between Generics statements when using out
and in
?
Example:
public class GenericClass<T> { }
public class GenericClassOut<out T> { }
public class GenericClassIn<T in> { }
5
The out
and the in
make the type generic covariant and countervariant, respectively.
An example of a covariant type is the IEnumerable
:
public interface IEnumerable <out T>: IEnumerable
{
IEnumerator<T> GetEnumerator();
}
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
As the function of a IEnumerable
is to iterate over the members of a list, and every object of a more specific type can be assigned to a variable of a more general type (i.e. an object string
can be stored in a variable object
), then an object that "produces" a string sequence can also be used as "an object that produces a sequence of objects". The returned elements will be the same (the strings in the list), but their static type will be object
and not string
.
The opposite is not true: a IEnumerable
that produces a sequence of objects cannot be used [securely] in a context that expects a string sequence (since it can also produce things that are not strings).
An example of a contravariant type is IComparer
:
public interface IComparer<in T>
{
int Compare(T x, T y);
}
IComparer<object> objects = ...;
IComparer<string> strings = objects;
In this case the relationship is opposite: if a IComparer
is able to compare any objects, it is also able to compare strings (because a string is an object). So it can be used in a context that requires a string comparator. The opposite is not true, because a comparator who only knows how to compare strings cannot be used to compare arbitrary objects.
Finally, an example of type invariant (which is neither co- nor contravariant) is itself IList
:
IList<string> strings = new List<string>();
IList<object> objects = new List<objects>();
How much the list accepted how much returns objects of the specified type cannot be assigned strings = objects
(because the list could already contain elements that are not strings) nor objects = strings
(because the list should not be able to receive elements that are not strings). Conversion in both directions is prohibited, so as to ensure type safety. So that neither the in
nor the out
shall be used in the generic type declaration:
public interface IList<T> ...
Thanks for the reply. I had to read it several times to understand!! = D rs.. Thanks!
Browser other questions tagged c# generic
You are not signed in. Login or sign up in order to post.
I believe your question has already been answered at: 
 http://stackoverflow.com/questions/10956993/out-t-vs-t-in-generics
– Ivan Teles
@Ivanteles Yes, but it would be nice to have an answer in Portuguese. Feel free to write one, or even translate some of the English (quoting the source, of course).
– bfavaretto
And there’s the
in
too, please!– JamesTK
Related: "What are covariance and countervariance?". I do not consider this question duplicated (because these concepts are more general, applying not only to generic types but also to other contexts, such as input and output of functions), so I gave a more contextualized answer below, without getting into the merit of explaining in detail the concepts.
– mgibsonbr