I made the following code:
using System;
public class Program
{
public static void Main()
{
//Este método funciona
Metodo(new ClasseTeste(){ Obj = new Registro(){ Nome = "Nome Teste"}});
//Este não
Metodo2(new ClasseTeste(){ Obj = new Registro(){ Nome = "Nome Teste2"}});
//Este não
Metodo3(new ClasseTeste(){ Obj = new Registro(){ Nome = "Nome Teste3"}});
}
public static void Metodo<T>(IBase<T> parametro) where T: class,IRegistro
{
string nome = parametro.Obj.Nome;
Console.WriteLine(nome);
}
public static void Metodo2(IBase<IRegistro> parametro)
{
string nome = parametro.Obj.Nome;
Console.WriteLine(nome);
}
public static void Metodo3(Teste<IRegistro> parametro)
{
string nome = parametro.Obj.Nome;
Console.WriteLine(nome);
}
}
Registration:
public interface IRegistro
{
string Nome {get;set;}
}
public class Registro : IRegistro
{
public string Nome {get;set;}
}
Generic interface and implementation:
public interface IBase<T> where T : class
{
T Obj {get;set;}
}
public abstract class Teste<T> : IBase<T> where T : class, IRegistro
{
public T Obj {get;set;}
}
public class ClasseTeste : Teste<Registro>
{
}
The first method Metodo
works, the other two do not.
The following error is returned:
Cannot convert ClasseTeste to IBase<IRegistro>
Question:
Why can not I convert an object that implements the interface, in its own interface?
I put it in DotNetFiddle
Edit:
After reading about Variance in generic interfaces (C #)
I changed the code to a covariant interface:
using System;
public class Program
{
public static void Main()
{
Metodo(new ClasseTeste(){ Obj = new Registro(){ Nome = "Teste 1"} });
Metodo2(new ClasseTeste(){ Obj = new Registro(){ Nome = "Teste 2"} });
//Metodo3(new ClasseTeste());
}
public static void Metodo<T>(IBase<T> parametro) where T: class,IRegistro
{
string nome = parametro.GetObj().Nome;
Console.WriteLine(nome);
}
public static void Metodo2(IBase<IRegistro> parametro)
{
string nome = parametro.GetObj().Nome;
Console.WriteLine(nome);
}
public static void Metodo3(Teste<IRegistro> parametro)
{
string nome = parametro.GetObj().Nome;
Console.WriteLine(nome);
}
}
public interface IRegistro
{
string Nome {get;set;}
}
public class Registro : IRegistro
{
public string Nome {get;set;}
}
public interface IBase<out T> where T : class, IRegistro
{
//T Obj{get;set;} //Erro (O Parametro T precisa ser invariante. T é Covariante
T GetObj ();
//void MetodoX(T obj); //Erro (O Parametro T precisa ser invariante. T é Covariante
}
public abstract class Teste<T> : IBase<T> where T : class, IRegistro
{
public T Obj {get;set;}
public T GetObj ()
{
return this.Obj;
}
}
public class ClasseTeste : Teste<Registro>
{
}
The method that expects
IBase<IRegistro>
will acceptClasseTeste
, but in the interface I can not declare properties or methods with generic type parameters.