Getting specific method from inherited class

53 views Asked by At

I have below object model with simple inheritance:

public class RuntimeApiManagerBase
{
}

public class CatalogRuntimeApiManagerBase : RuntimeApiManagerBase
{
    public void Method1()
    {
    }
}

public class DocumentRuntimeApiManagerBase : RuntimeApiManagerBase
{
    public void Method2()
    {
    }

    public void Method3()
    {
    }
}

public class BaseObject
{
    public BaseObject(RuntimeApiManagerBase runtimeApiMgr)
    {
        RuntimeApiMgr = runtimeApiMgr;
    }
    public RuntimeApiManagerBase RuntimeApiMgr { get; set; }
}

public class Catalog : BaseObject
{
    public Catalog() : base(new CatalogRuntimeApiManagerBase())
    {
    }
}

public class Document : BaseObject
{
    public Document() : base(new DocumentRuntimeApiManagerBase())
    {
    }
}

Now, I want to access RuntimeApiMgr Property's Methods based on exactly derived type. However, it displays nothing which is logical:

Catalog c1 = new Catalog();

// c1.RuntimeApiMgr. => No Method1

Document d1 = new Document();
// d1.RuntimeApiMgr. => No Method2 and Method3

Is that possible using different structure like Generics or something else?

Thanks for your time.

3

There are 3 answers

0
Maksim Simkin On BEST ANSWER

Use generics:

public class BaseObject<T>
  where T : RuntimeApiManagerBase
{
    public BaseObject(T runtimeApiMgr)
    {
        RuntimeApiMgr = runtimeApiMgr;
    }
    public T RuntimeApiMgr { get; set; }
}

public class Catalog : BaseObject<CatalogRuntimeApiManagerBase>
{
    public Catalog() : base(new CatalogRuntimeApiManagerBase())
    {
    }
}

public class Document : BaseObject<DocumentRuntimeApiManagerBase>
{
    public Document() : base(new DocumentRuntimeApiManagerBase())
    {
    }
}

In that case your c1.RuntimeApiMgr will be of the type CatalogRuntimeApiManagerBase and will have Method1

0
Marko Juvančič On

Alternative to solution with generics is an old fashioned approach with casting. Maybe something like this:

Catalog c1 = new Catalog();
(c1.RuntimeApiMgr as CatalogRuntimeApiManagerBase).Method1();


Document d1 = new Document();
(d1.RuntimeApiMgr as DocumentRuntimeApiManagerBase).Method2();

Or create new properties with the same name in Caltalog and Document classes:

public class Catalog : BaseObject
{
  public Catalog() : base(new CatalogRuntimeApiManagerBase())
  {
  }

  public new CatalogRuntimeApiManagerBase RuntimeApiMgr { get; set; }
}
0
Serve Laurijssen On

You can use RuntimeApiManagerBase as generic and have a type constraint where T must be a subclass of RuntimeApiManagerBase

    public class BaseObject<T> where T : RuntimeApiManagerBase
    {
        public BaseObject(T runtimeApiMgr)
        {
            RuntimeApiMgr = runtimeApiMgr;
        }
        public T RuntimeApiMgr { get; set; }
    }

    public class Catalog : BaseObject<CatalogRuntimeApiManagerBase>
    {
        public Catalog() : base(new CatalogRuntimeApiManagerBase())
        {
        }
    }

    public class Document : BaseObject<DocumentRuntimeApiManagerBase>
    {
        public Document() : base(new DocumentRuntimeApiManagerBase())
        {
        }
    }

    Catalog c1 = new Catalog();

    c1.RuntimeApiMgr.Method1();

    Document d1 = new Document();
    d1.RuntimeApiMgr.Method2();