2012-06-21 117 views
0

可能是我無法用言語什麼,我試圖實現準確解釋,但我認爲這個示例代碼可以做:擴展類

class A 
{ 
    public string Name 
    { 
     get; 
     set; 
    } 
    public virtual void Say() 
    { 
     Console.WriteLine("I am A"); 
     Console.Read(); 
    } 

    public bool ExtendA; 

    public A GetObject() 
    { 
     if (ExtendA) 
      return new B(); 

     return this; 
    } 
} 

internal class B : A 
{ 
    public override void Say() 
    { 
     Console.WriteLine(string.Format("I am {0}",Name)); 
     Console.Read(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    {   
     var a = new A() {ExtendA = true,Name="MyName"}; 
     A ab = a.GetObject();    
    } 
} 

按照上面的代碼字段時Exitend A被設置爲true,並且當我再次嘗試從同一個對象實例中獲取相同類型的對象時,我得到該對象,但它丟失了屬性「Name」的值。

任何建議如何返回具有屬性A的類B?

謝謝

+2

你爲什麼會以這種方式工作?這是沒有意義的... 父類應該**永遠**實例化一個孩子類! –

+0

由於您返回了一個全新的實例,您將失去* ALL *屬性... – Tisho

+0

@Tisho是對的,您可以爲B構造一個接受A的實例並複製屬性的構造函數 – Fr33dan

回答

5

我建議你讀一本書或其他設計模式的資源。爲此,您將使用工廠模式。

除了類B : A和類BFactory之外,您還需要基類A和類AFactory

在運行時,你會選擇你想要實例什麼:A或B通過工廠:

IFactory的工廠= iWantClassA?新的AFactory():new BFactory(); A a = factory.CreateInstance();

雖然我同意@ArnaudF,但我沒有看到你想要完成的事情。爲什麼不直接創建子類B?

UPDATE:

有重讀你的問題聽起來好像你真的只需要在你的類定義拷貝構造函數,像這樣:

public class A { 
    public A() { 
     // Default constructor 
    } 
    public A(A other) { 
     // Copy-constructor. Members of other will be copied into this instance. 
    } 
} 

public class B : A { 
    public B() { 

    } 
    public B(A other) : base(other) { // Notice how it calls the parent class's copy-constructor too 
    } 
} 

然後「升級」一個實例到B在運行時的一個實例,只需要使用拷貝構造函數:

A a = new A(); 
// some logic here 
B upgradedA = new B(a); 
1

我不知道你在做什麼的最終目的是,但我希望讓你知道ExpandObject型的,萬一你不要不知道。

這可以讓你動態在運行時的屬性和方法添加到對象,因爲這樣的代碼說明:

using System; 
using System.Dynamic; 

namespace Demo 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      dynamic expando = new ExpandoObject(); 

      expando.Name = "Name"; // Add property at run-time. 
      expando.PrintName = (Action) (() => Console.WriteLine(expando.Name)); // Add method at run-time. 

      test(expando); 
     } 

     private static void test(dynamic expando) 
     { 
      expando.PrintName(); 
     } 
    } 
}