0

I am coming across an error that I have not seen before. I am hoping some one can help.

Here is my code:

public class MyT
{
    public int ID { get; set; }
    public MyT Set(string Line)
    {
        int x = 0;

        this.ID = Convert.ToInt32(Line);

        return this;
    }
}

public class MyList<T> : List<T> where T : MyT, new()
{
    internal T Add(T n)
    {
        Read();
        Add(n);
        return n;
    }
    internal MyList<T> Read()
    {
        Clear();
        StreamReader sr = new StreamReader(@"../../Files/" + GetType().Name + ".txt");
        while (!sr.EndOfStream)
            Add(new T().Set(sr.ReadLine())); //<----Here is my error!
        sr.Close();
        return this;
    }
}

public class Customer : MyT
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Item : MyT
{
    public int ID { get; set; }
    public string Category { get; set; }
    public string Name { get; set; }
    public double Price { get; set; }
}

public class MyClass
{
    MyList<Customer> Customers = new MyList<Customer>();
    MyList<Item> Items = new MyList<Item>();
}

On the line that says, "Add(new T().Set(sr.ReadLine()));" I get "Error 7, Argument 1: cannot convert from 'Simple_Reservation_System.MyT' to 'T'". Can someone please help me fix this.

Makai
  • 567
  • 3
  • 9
  • 18
  • Frankly this is not very "generic", why don't you just use List inside of MyList ? – Dimitar Dimitrov May 10 '13 at 07:35
  • Short version: you are trying to put a `MyT` object into a list that could be required to contain any arbitrary subclass of `MyT`, per your constriant. See marked duplicate for why this is dangerous and not allowed. What's the appropriate way to fix it cannot be known without a lot more detail about your problem. But really, you should just study the problem and decide for yourself what it is you actually want to have happen. – Peter Duniho Nov 05 '19 at 07:08

3 Answers3

0

Your type MyList can only contain elements of type "T" (specified when the list is declared). The element you are trying to add is of type "MyT", which cannot be downcasted to "T".

Consider the case in which MyList is declared with another subtype of MyT, MyOtherT. It is not possible to cast MyT to MyOtherT.

Andreas
  • 1,751
  • 2
  • 14
  • 25
  • Could you give me an example? – Makai May 10 '13 at 07:58
  • There is an example in your code: class Customer derives from MyT. So to illustrate the error: on the problematic line, you would be attempting to cast an object of Type "MyT" to type "Customer" which is not allowed. You can always cast to a supertype, but never to a subtype. – Andreas May 10 '13 at 08:49
  • I get that. Now how do I fix it? – Makai May 10 '13 at 09:14
  • Rather than using the Set function with its explicit return type, you should put that logic into the constructor of the type. Your file read is probably different anyway depending on whether you're reading a customer, or an item. – Andreas May 10 '13 at 09:23
0

Your Add parameter takes the generic type T. Your Set method return a concrete class MyT. It is not equal to T. In fact even if you call this:

Add(new MyT())

it will return an error.

I would also like to add that this is an error only while you are inside the MyList class. If you call the same method from a different class it will work.

bobbyalex
  • 2,681
  • 3
  • 30
  • 51
0

Because your type MyT is not the same that generic parameter T. When you write this new T() you create an instance of type T that must be inherited from MyT, but this is not necessarily the type of MyT. Look at this example to see what I mean:

public class MyT1 : MyT
{

}
//You list can contains only type of MyT1
var myList = new MyList<MyT1>();

var myT1 = new MyT1();
//And you try to add the type MyT to this list.
MyT myT = myT1.Set("someValue");
//And here you get the error, because MyT is not the same that MyT1.
myList.Add(myT);
Vyacheslav Volkov
  • 4,592
  • 1
  • 20
  • 20
  • Okay. So how do I fix it? – Makai May 10 '13 at 07:50
  • I don't know details of your task. For example you can inherit your `MyList` class from `List`, and then your class will not be generic. But it would be better if you create a class that will be responsible for reading the file and returns an instance of `List `. – Vyacheslav Volkov May 10 '13 at 07:59