Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# implicit conversion from base class

I have a collection class like this:

public class SomeDataCollection : List<ISomeData>
{
    // some method ...
}

but I can't do this:

SomeDataCollection someDatas = new List<ISomeData>();

Cannot implicitly convert type List<ISomeData> to SomeDataCollection. An explicit conversion exists (are you missing a cast?)

so I try to create an implicit coverter inside SomeDataCollection collection class:

public static implicit operator SomeDataCollection(List<ISomeData> l)
{
    var someDatas = new SomeDataCollection();
    someDatas.AddRange(l);
    return someDatas;
}

but it said that I can't create such converter:

SomeDataCollection.implicit operator SomeDataCollection(List<ISomeData>): user-defined conversions to or from a base class are not allowed

And when I cast it like this:

SomeDataCollection someDatas = (SomeDataCollection)new List<ISomeData>();

it throws an error that said:

System.InvalidCastException: Unable to cast object of type List<ISomeData> to type SomeDataCollection.

How can I do this:

SomeDataCollection someDatas = new List<ISomeData>();

without getting an error? Please help. Thanks in advance.

like image 613
John Isaiah Carmona Avatar asked Jun 27 '12 07:06

John Isaiah Carmona


1 Answers

A new List<ISomeData>(); is still just a List<ISomeData>. It isn't a SomeDataCollection. The point of subclassing is that the subclass could have extra state etc, but an object (once created) never changes type.

You are not allowed to create operators between types in the same hierarchy, as that would subvert the usual and expected casting behaviour.

You could use simply:

var data = new SomeDataCollection();

However I should add that frankly it is rarely useful to subclass List<T>. Not least, it doesn't expose any useful virtual methods, so you can't tweak the behaviour. I would honestly just use a List<ISomeData> (and remove SomeDataCollection completely) unless I have a clear and demonstrable purpose for it. And then: I might either encapsulate the list, or inherit from Collection<T>.

You could always just add the method as an extension method?

public static class Utils {
    public static void SomeMethod(this IList<ISomeData> list) {
      ...
    }
}

then:

var list = new List<ISomeData>();
...
list.SomeMethod();
like image 113
Marc Gravell Avatar answered Sep 21 '22 15:09

Marc Gravell