2015-07-09 21 views
0

所以說我有三個類:A,B和C.A是抽象的,B和C繼承自A.正在使用反射來查找代碼氣味的抽象屬性的類型?

我創建了A類的列表。在函數中,我需要知道我有的類的類型:A,B或C.我是否使用反射來獲取名稱?分配一個類型變量並檢查?還是我使用抽象從根本上錯誤?

public abstract class A 
{ 
    public string Type 
    { 
     get; 
     set; 
    } 
} 
public class B : A 
{ 
    public B() 
    { 
     this.Type = "B"; 
     Console.WriteLine("I am of type B!"); 
    } 
} 
public class C : A 
{ 
    public C() 
    { 
     this.Type = "C"; 
     Console.WriteLine("I am of type C!"); 
    } 
} 

List<A> listOfStuff = new List<A>(); 
void doSomething() 
{ 
    listOfStuff.Add(new A()); 
    listOfStuff.Add(new B()); 
    listOfStuff.Add(new C()); 

    foreach (A item in listOfStuff) 
    { 
     doOperation(item); 
    } 
} 
void doOperation(A thing1) 
{ 
    //Is this bad practice? 
    if (thing1.GetType().Name == "B") 
    { 
     //Do code 
    } 
    //Or what about this? 
    if (thing1.Type == "B") 
    { 
     //Do code 
    } 
} 
+1

這兩個'doOperation'中的檢查都會給你帶來麻煩,因爲處理的類型列表會增加。你想做什麼?爲什麼不使用相關類型可以實現的接口? – xxbbcc

+5

看起來你只是在這裏尋找*虛擬方法*。 –

+0

問題可能更適合http://programmers.stackexchange.com/ – Sam

回答

1

這可能違反了Liskov substitution principle,L SOLID.如果一堆「A」在列表中,應該可以在不知道它們的子類型的情況下對它們進行操作。如果他們都將被視爲A,但是你必須重新檢查他們以確定他們的實際類型並且以不同的方式處理它們,那麼它就會失去能夠以其基本類型來引用它們的目的。

如果不同的類型可以暴露相同的屬性(描述區域,尺寸等),那麼接口可能比抽象類更好。

+0

這是一個有洞察力的閱讀,謝謝! – MiddaPhofidda

1

沒有必要努力工作。只需使用is

public abstract class A 
{ 
} 

public class B : A 
{ 
    public B() 
    { 
     Console.WriteLine("I am of type B!"); 
    } 
} 
public class C : A 
{ 
    public C() 
    { 
     Console.WriteLine("I am of type C!"); 
    } 
} 

static List<A> listOfStuff = new List<A>(); 
public static void doSomething() 
{ 
    listOfStuff.Add(new B()); 
    listOfStuff.Add(new C()); 

    foreach (A item in listOfStuff) 
    { 
     doOperation(item); 
    } 
} 
static void doOperation(A thing1) 
{ 
    if (thing1 is B) 
    { 
     //Do code for B 
    } 

    if (thing1 is C) 
    { 
     //Do code for C 
    } 
} 
1

羅布心肝已經表明您如何避免這樣做,但他沒有具體回答你的問題。

我會說「代碼味道」對於你在OP中寫的內容太過溫和。我可以看到使用反射來查找對象類型的唯一好例子是某種日誌記錄或報告功能。 (有些東西會打印出「我得到了一個B」。)如果需要解決無法修復的代碼中的錯誤,那麼這將是可能的。除此之外,不要這樣做。