2016-12-30 78 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();