1

What i really want is to understand is why when using an interface as a constraint on a generic class I am able to access the "Nume" property that I defined in a class that implements that interface. My questions are:

    1. Why do I have to add the interface as a constraint in the generic class while I already implemented it in the initial Tr class?
    1. Why I cannot access the property directly from the class and why I am able to access it by implementing the interface?

Without the interface I cannot access the property from the Tr class, so I implemented the solution found on this Stackoverflow question,it seems to work but i cannot understand exactly why.

I also looked on this Microsoft documentation.

interface GET
{
    int Nume { get; }
}

class Tr : GET 
{
    public int Nume { get; }

    public Tr() { }

    public Tr(int num)
    {
        this.Nume = num;
    }
}

class Program<Tr> where Tr : GET
{
   static List<Tr> lst = new List<Tr>();

    public void Test(Tr merge)
    {           
        lst.Add(merge);
        foreach (Tr cadt in lst)
        {
            Console.WriteLine($"Numarul este {cadt.Nume}");
        }
    }     
}

class MainC
{      
    static void Main(string[] args)
    {
        Tr cc = new Tr(2);

        Program<Tr> cls = new Program<Tr>();
        cls.Test(cc);
    }        
}

I expected This code to work without the help of an interface, but it crashed. It works with the help of the interface.

CSDev
  • 3,177
  • 6
  • 19
  • 37
Daniel
  • 261
  • 3
  • 18
  • "but it crashed" isn't helpful, what was the exact error? Include the message in your question. The code you posted runs without error, we need more information. – DavidG Jun 16 '19 at 18:47
  • @Workout Channel, as I got that from the question, the error was there without `where Tr : GET` constraint and you had to add it to fix the error. Right? – CSDev Jun 16 '19 at 19:13
  • @Alex Yes.I used the solution provided in the stackoverflow link,but the reason why I posted this question is hopefully someone to explain me why,by implementing the interface,the code worked. – Daniel Jun 16 '19 at 19:25
  • @Workout Channel, see the update to my answer. It gives all the explanation. – CSDev Jun 17 '19 at 09:05
  • Thank You @Alex.So,from my understanding:The is just a type parameter,it has nothing to do with the actually Tr class and it can be replace by anything.The compiler knows of the Nume property because the type parameter implements the interface on which the Nume property is defined,so to compiler now knows that the object that will replace the has to contain the Nume property.Correct me if I am wrong please. – Daniel Jun 17 '19 at 09:48
  • Also 2 more questions: You always need to implement the interface as a constraint to the generic in order to access the properties from a class? The property Nume is accessed directly from the interface or,I guess,is accessed at runtime from the Tr class and the interface is just a reference? – Daniel Jun 17 '19 at 09:49
  • @Workout Channel, you got it right. For your first question it is yes. For the second one read more about implicit and explicit interface implementation. – CSDev Jun 17 '19 at 09:58

1 Answers1

1

In class Program<Tr> where Tr : GET Tr is a type parameter, it's just a name and it has nothing to do with Tr class. So it does not implement GET and it does not have to provide Nume property. But if you put the constraint where Tr : GET the situation changes. Now it does implement GET and it does have to provide Nume property.

Your class is equivalent to:

class Program<T> where T : GET
{
    static List<T> lst = new List<T>();

    public void Test(T merge)
    {
        lst.Add(merge);
        foreach (T cadt in lst)
        {
            Console.WriteLine($"Numarul este {cadt.Nume}");
        }
    }
}

This is the reason why

  • you have to add the interface as a constraint in the generic class
  • you cannot access the property directly from the class
  • you are able to access it by implementing the interface

Using <Tr> makes confusion. If I were a compiler developer I'd treat it as an error (a warning at least) and I wouldn't let such a code to compile.

Here is an illustration of <Tr> in class Program<Tr> is not Tr class. enter image description here

CSDev
  • 3,177
  • 6
  • 19
  • 37
  • How can you possibly answer the question when it isn't even complete? The code posted runs without error. – DavidG Jun 16 '19 at 18:57
  • @DavidG, as I got that from the question, the error was there without `where Tr : GET` constraint and OP had to add it to fix the error. – CSDev Jun 16 '19 at 19:05