2016-12-30 82 views
2

具体的方法我有以下简单的继承对象模型:充分利用继承

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()) 
    { 
    } 
} 

现在,我希望根据准确派生类型访问RuntimeApiMgr属性的方法。然而,它没有显示任何合乎逻辑的东西:

Catalog c1 = new Catalog(); 

// c1.RuntimeApiMgr. => No Method1 

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

这可能使用不同的结构,如泛型或其他?

谢谢你的时间。

回答

4

使用泛型子类:

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()) 
    { 
    } 
} 

在这种情况下,你的c1.RuntimeApiMgr将是类型CatalogRuntimeApiManagerBase的,将有Method1

1

替代解决方案与泛型是一种老式的铸造方法。 也许是这样的:

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


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

或创建Caltalog具有相同名称的新属性和文档类:

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

    public new CatalogRuntimeApiManagerBase RuntimeApiMgr { get; set; } 
} 
4

您可以使用RuntimeApiManagerBase作为通用的,有一个类型约束,其中T必须是的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();