Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can this generic type not be converted?

Tags:

c#

generics

Say I have the following three classes/interfaces:

public interface IImportViewModel
{

}

public class TestImportViewModel : IImportViewModel
{

}

public class ValidationResult<TViewModel> where TViewModel : IImportViewModel
{

}

As TestImportViewModel implements IImportViewModel, why will the following not compile?

ValidationResult<IImportViewModel> r = new ValidationResult<TestImportViewModel>();

I understand what the error message "Cannot implicitly convert type 'ValidationResult' to 'ValidationResult'" means. I just don't understand why this is the case. Would this not be covariance?

like image 811
devlife Avatar asked Jul 02 '12 13:07

devlife


People also ask

Is it possible to inherit from a generic type?

An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.

How do you know if a type is generic?

To examine a generic type and its type parametersGet an instance of Type that represents the generic type. In the following code, the type is obtained using the C# typeof operator ( GetType in Visual Basic, typeid in Visual C++). See the Type class topic for other ways to get a Type object.

Can a generic be null?

This means that you can put any object in a collection because all classes in the C# programming language extend from the object base class. Also, we cannot simply return null from a generic method like in normal method. Below is the error that a generic method will throw if we are trying to return null.


1 Answers

Would this not be covariance?

Yes, except that in C# 4.0 covariance works on interfaces only. So you will have to make your ValidationResult implement a covariant interface (one for which the generic parameter is defined as out):

public interface IImportViewModel
{
}

public class TestImportViewModel : IImportViewModel
{
}

public interface IValidationResult<out TViewModel> where TViewModel : IImportViewModel
{
}

public class ValidationResult<TViewModel> : IValidationResult<TViewModel> where TViewModel : IImportViewModel 
{
}

and now you can do this:

IValidationResult<IImportViewModel> r = new ValidationResult<TestImportViewModel>();
like image 145
Darin Dimitrov Avatar answered Sep 28 '22 00:09

Darin Dimitrov