Search code examples
c#collectionsderived-class

collection of derived class


I’m refactoring my code of separation of concern (SoC). Move non-AutoCAD code away to separate dll, so Common, Data Access, web service, AutoCAD related, … in different dll files.

Here is sample of my class:

// non-AutoCAD dll
public class Loc
{
    public int Id;
    public string Name;
    ...
}

// AutoCAD dll
public class AcadLoc : Loc
{
    public ObjectId oid;
}

// non-AutoCAD dll
public class Locs : List<Loc>
{
    public Loc Get_By_Id(long id)
    {
        return this.SingleOrDefault(n => n.Id == id);
    }
}

// AutoCAD dll
public class AcadLocs : Locs // or List<AcadLoc> ? 
{
}

My question is, can I run something like

AcadLocs myAcadLocs = new AcadLocs();
AcadLoc myAcadLoc = myAcadLocs.Get_By_Id(1);   // How to make this works? 

I tried:

public class AcadLocs : Locs // or List<AcadLoc> ? 
{
    public AcadLoc Get_By_Id(int id)
    {
        return this.SingleOrDefault(n => n.Id == id);
    }
}

it would not works.

Now I change to this:

public interface ILocData<T> where T : new() {} 

// non-AutoCAD dll
public class Loc : ILocData<Loc>
{
    public int Id;
    public string Name;
    ...
}

// AutoCAD dll
public class AcadLoc : Loc, ILocData<AcadLoc>
{
    public ObjectId oid;
}

public class LocDataCollection<T, TCollection> : List<T>
    where T : ILocData<T>, new()
    where TCollection : LocDataCollection<T, TCollection>, new()
{
}

// non-AutoCAD dll
public class Locs : LocDataCollection<Loc, Locs>
{
    public Loc Get_By_Id(int id)
    {
        return this.SingleOrDefault(n => n.Id == id);
    }

    public bool Check()
    {
        foreach (Loc loc in this)
        {
        ....
        }
    }
}

// AutoCAD dll  
public class AcadLocs : LocDataCollection<AcadLoc, AcadLocs>
{
    public AcadLoc Get_By_Id(int id)
    {
        return this.SingleOrDefault(n => n.Id == id);
    }
}

Now,

AcadLoc myAcadLoc = myAcadLocs.Get_By_Id(1);   // works

but

myAcadLocs.Check();  // failed

Thanks

Wes


Solution

  • I think what you need is extension method

    public static class MyExtension 
    
    {
        public static Loc Get_By_Id(this Locs l,int id) 
        {
            return l.SingleOrDefault(n => n.Id == id);
        }
    
        public static bool Check(this Locs l)
        {
            foreach (Loc loc in l)
            {
            ....
            }
        }
    }
    

    Once you have this code in place then just call this methods like this

     myAcadLocs.Get_By_Id(1);
     myAcadLocs.Check();
     myLocs.Get_By_Id(1);
     myLocs.Check();