How to cast a typed class in C#?

Asked

Viewed 918 times

3

I own the class Carro who inherits from the class Objeto and another class CarroTeste implementing the abstract class TesteBase that by its implements the interface ITeste, both (TesteBase and ITeste) typed with restriction to use only class objects Objeto, the problem occurs when I try to instantiate a CarroTeste in an Iteste variable ITeste<Objeto> teste = new CarroTeste();, IDE says I can’t do an implicit type conversion. The class code is below.

public class Objeto
{
    protected string _nome;
    public string nome { get{return _nome;} }
}

public class Carro : Objeto
{
    public Carro()
    {
        _nome = "Carro";
    }
}

public interface ITeste<T> where T : Objeto
{
    string GetNome();
    List<T> List { get; }
    T GetChange(T obj);
}

public abstract class TesteBase<T> : ITeste<T> where T : Objeto
{
    protected Objeto _obj = null;
    public abstract string GetNome();
    public abstract List<T> List { get; }
    public abstract T GetChange(T obj);
}

public class CarroTeste : TesteBase<Carro>
{
    public override string GetNome()
    {
        return "Meu nome é : " + _obj.nome;
    }

    public override List<Carro> List
    {
        get { return new List<Carro>(); }
    }

    public override Carro GetChange(Carro obj)
    {
        return obj;
    }
}
  • During my tests with the answer given by bigwon I changed the interface to use the modifier out and implemented in the class CarroTeste a method called CarroToObjeto that through function ConvertAll of own List returns me a new list with the correct type, but obviously a List<Object> does not have all Car properties and methods. CarroTeste instead of the interface ITeste.

2 answers

3


Are you in trouble variance. To solve you must allow the interface to be used covariantly. See:

public class Program {
    public static void Main() {
        ITeste<Objeto> teste = new CarroTeste();
    }
}

public class Objeto {
    protected string _nome;
    public string nome => _nome;
}

public class Carro : Objeto {
    public Carro() => _nome = "Carro";
}

public interface ITeste<out T> where T : Objeto {
    string GetNome();
}

public abstract class TesteBase<T> : ITeste<T> where T : Objeto {
    protected Objeto _obj = null;
    public abstract string GetNome();
}

public class CarroTeste : TesteBase<Carro> {
    public override string GetNome() => "Meu nome é : " + _obj.nome;
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Note the line public interface ITeste<out T> where T : Objeto { using the modifier out to indicate the variance.

I don’t know if it solves the way you want it to, but it solves the immediate problem.

  • Kr this your tip solved one problem but caused another because the class I posted was a summary of the class I use. I will edit the question by placing the full class below this error when using the modifier out. Error 1 Invalid Variance: The type Parameter’T' must be contravariantly Valid on 'Windowsformsapplication1.Iteste<T>. Getchange(T)'. 'T' is covariant. C: Users Begins Desktop Job C# Windowsformsapplication1 Windowsformsapplication1 Test.Cs 23 33 Windowsformsapplication1

  • Then you changed the problem. Now I can’t see it. But it seems that the problem is further down.

  • I’m sorry bigwon I didn’t imagine that the other functions would interfere with the problem because completely unaware of the variance.

1

Your code is correct, the . NET just doesn’t do the implicit conversion (without you asking).

Explicitly convert the object:

ITeste<Objeto> teste = (ITeste<Objeto>) new CarroTeste();

That one (tipo) instructs the conversion of what comes next. In this case, it is what we call explicit conversion.

This behavior exists to avoid conversions without the programmer wanting. If that happened and caused any trouble, it would be very, very difficult to trace.

  • when using the function I got the error: "Error 1 'Windowsformsapplication1.CarroTeste.implicit Operator Windowsformsapplication1.Iteste<Windowsformsapplication1.Carro>(Windowsformsapplication1.Carroteste)': user-defined conversions to or from an interface are not allowed C: Users Begins Desktop Job Tests C# Windowsformsapplication1 Windowsformsapplication1 Test.Cs 54 23 Windowsformsapplication1 "

  • true, but the first way works?

  • Unfortunately I have not tried various forms of Cast explicitly the only compiled was ITeste<Objeto> teste = new CarroTeste() as ITeste<Objeto>; and even then it doesn’t work, the error occurs at runtime which is more dangerous. Faced with this fact I will no longer use this type of Cast in any situation.

  • A hammer can hurt if used incorrectly. Therefore, it should never be used.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.