0

I'm stuck with this problem for several hours. I'm trying to find an equivalent method for C#.

Java, works:

public class Main
{
  public static void main(String[] args)
  {
    ArrayList<BaseList<? extends Base>> list = new ArrayList<>();
    list.add(new DerivedList());
  }
}

public class BaseList<T extends Base>
{

}

public class Base
{

}

public class DerivedList extends BaseList<Derived>
{

}

public class Derived extends Base
{

}

I need an equivalent method for ArrayList<BaseList<? extends Base>> in C#. I hope someone help me.

And is it posible in C# to wildcard your variables??

boraida
  • 3
  • 4

2 Answers2

1

C# uses runtime type reification, whereas Java uses type erasure. Which means that in Java, ArrayList<Foo> is the same class as ArrayList<Bar> at runtime. This is not the case in C#, so you can't just throw away the type parameter like that.

You can try to work around that like this:

public abstract class BaseList
{
}

public class BaseList<T> : BaseList
    where T : Base
{
}

Then use a List<BaseList>

Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
  • Thank you! But do you know how can I access a property in `BaseList` form an element in the `List`? – boraida Nov 16 '16 at 09:56
  • @boraida If it doesn't depend on `T`, move it to `BaseList` instead. You haven't provided the definition of your classes, so I can't say much more. – Lucas Trzesniewski Nov 16 '16 at 10:00
  • It actually depends on `T`. The property is `public virtual List Entries { get; }`, made it virtual so the derived class can override it and add the `XmlElement` attribute to it. Any tips to achieve this? – boraida Nov 16 '16 at 10:16
1

You cannot do that exactly as you describe, but there are workarounds. One is mentioned in another answer, another is to use interface instead:

public class Main
{
    public static void main(String[] args)
    {
        var list = new List<IBaseList<Base>>();
        list.Add(new DerivedList());
    }
}
// note "out" here
public interface IBaseList<out T> where T : Base {

}

public class BaseList<T> : IBaseList<T> where T : Base {

}

public class Base {

}

public class DerivedList : IBaseList<Derived> {

}

public class Derived : Base {

}
Evk
  • 98,527
  • 8
  • 141
  • 191
  • If I'm using this method I'm having the same problem as mentioned in the comments of Lucas Trzesniewski – boraida Nov 16 '16 at 10:20
  • You cannot declare "List Entries" property in that interface, because it will violate variance (that "out" keyword). However, you can declare it as "IEnumeable Entries" if that will suite your needs. – Evk Nov 16 '16 at 10:24