Casting List<base> to List<ireadonlybase> where base implements ireadonly

Hi All,

I'm having problems implementing a readonly interface to a set of classes.
Heres a simplification of the code:

interface IreadonlyBase
{ // Does gets only on base class
}

class baseclass : IreadonlyBase
{ // Does gets and sets as usual
}

interface IreadonlyDerived : Ireadonlybase
{ // Does gets only on derived class & base class
}

class derivedclass : baseclass, IreadonlyDervied
{ // Does gets and sets as usual
}

class container
{
private List<baseclass> baseclassitems;
public ReadOnlyCollection<Ireadonlybase> ReadOnlyBases
{
// Should return a readonly version of the baseclassitems that can be traversed
get{return new ReadOnlyCollection<IReadOnlyEntity>(baseclassitems)};
}
}

Problem is the compiler refuses to accept the baseclassitems as a list of Ireadonly even though each base class derives from Ireadonly, why can i not cast a List<baseclass> to List<Ireadonlybase> if every base is a Ireadonly base
I don't want to have to recreate the baselist again (in terms of interfaces) just to access it in a readonly manner.
Is this a logical approach to the readonly problem or am i overlooking something completely more obvious!

Many thanks for any help you can give.


Answer this question

Casting List<base> to List<ireadonlybase> where base implements ireadonly

  • aaks

    Hi,

    I could be a little mixed up with the generics here, but I beleive that it's because the List generic instantiated with one type, is not the same class, or a derived class of another list with a different class, even though it is derived (essentially saying List<classA> is not the same as List<classB> even if class B subclasses classA).

    You can add elements of classB to the List<classA> if classB is derived from classB.

    If your MyClass implements IReadOnlyMyClass, you should be able to add an element of MyClass to List<IReadOnlyMyClass>, but not the other way around.

    Cheers,

    Stephen


  • Chitai Liu

    Hi

    As micvos says a List<IBaseInterface> is not the same as List<BaseImpl>, even though the BaseImpl class implements IBaseInterface.

    When you create a List<sometype>, then it byself is a distinct type.

    I am not sure if there is some facility in the BCL to convert a list of objects to list of interfaces, where bases implement the interfaces.

    But some code like this might help:-

    // BaseImpl[] bimplArray = GetBaseImplArray();
    IBaseInterface[] baseInterfaces = Array.ConvertAll(bimplArray, delegate(BaseImpl baseImpl)
    {
        return baseImpl as IBaseInterface;
    });
    
    Array.ForEach(baseInterfaces, delegate(IBaseInterface bi)
    {
        Console.WriteLine(bi.GetIndex());
    });
    Let us know if you come to know a good performance method of achieving the conversion.
    Regards

  • Recency

    Hi

    Yes sorry thats a typo!

    IReadOnlyEntity should read ireadonlybase! - I still do not have a solution.

    What i'm really looking for is a cycle inexpensive readonly view of a classes list data. I thought i might be able to acomplish this with the readonly collection coupled with the use of some defined readonly interfaces to the lists i'm interested in.

    Thanks anyway for taking timeout to look at the problem.


  • aschaeffer

    Hi,

    Sorry for disturbing u , like if ur problem is solved , could u please post the solution

    Thanx in advance,

    Ch.T.Gopi Kumar.



  • jomunoz

    List<baseclass> and List<Ireadonlybase> are to separate classes and List<baseclass> does not inherit form List<Ireadonlybase>.

  • e_LA

    You are correct, baseclass does not inherit from ireadonlybase

    but, baseclass does in every case implement the interface necessary to implement Ireadonlybase so i really don;t see why they can;t be casted.

    To be honest i'm not entirely happy with the solution and i'm looking for a more general approach to providing a readonly view of data to the outside of a class.


  • prashant mulay

    Hi,

    How you defined ReadOnlyCollection And what exactly you want to do in the example

    It must be a way to walk around, I think.

    Thank you



  • Kinlan

    Hi,

    what is IReadOnlyEntity here

    And u cannot cast a base class reference to a child class reference and ofcourse the reverse is possible.

     

     

    Thanx,

    Ch.T.Gopi Kumar.



  • John_Wesley

    Hi

    ReadOnlyCollection comes from the System.Collections.ObjectModel namespace and seems to be a wrapper that enables some readonly functionality. It prevents the add/deleting from the list in question but does not protect the actual content.

    The end goal for my code was to provide a readonly view of a list of classes without having to recreate the original list in terms of interfaces as performance is key for me here.

    class MyClass : IReadOnlyMyClass
    {//Contains gets and sets on its members}

    interface IReadOnlyMyClass{//Only contains gets on its members to make them readonly (value types!)}

    class ContainerClass
    {
    private List<MyClass> mClassitems;
    ReadOnlyCollection<IReadOnlyMyClass> mReadOnlyList = new ReadOnlyCollection(mClassItems);

    public ReadOnlyCollection<IReadOnlyMyClass> ReadOnlyList
    {
    // Should return a readonly version of the classitems
    get {return mReadOnlyList};
    }
    }

    This was to be a way to share the list data of a class while keeping encapsulation but the cast from List<MyClass> to List<IReadOnlyMyClass> does not work even though every MyClass instance implements the interface necessary for IReadOnlyMyClass. Perhaps i've gone about this the wrong way and there is another way to readonly access the contents of a class without all this but i cannot see it!

    Thanks for taking time out to look at the problem


  • Casting List<base> to List<ireadonlybase> where base implements ireadonly