2014-09-05 70 views
1

嗨具有實現一個interface.I幾個班想I負荷列表的項目轉換成其具體類這樣的他們,我想打電話給工廠轉換器獲得另一種類型。從接口類型轉換爲具體類型在C#和反思

+2

爲什麼?如果你只是沮喪,接口的意義何在?你甚至不知道什麼屬性/方法可用。如果你做了/被演員,至少你知道類型。 – BradleyDotNET 2014-09-05 16:44:30

+0

所以它不工作? – 2014-09-05 16:44:35

+1

http://en.wikipedia.org/wiki/Polymorphism_(computer_science) – BlackBear 2014-09-05 16:44:38

回答

3

您可以使用dynamic類型like this

List<ILoad> list = new List<ILoad>(); 
list = GetALlIloads(); 

Factory f = new Factory(); 

foreach (var item in list) 
{ 
    dynamic concreteType = item; 
    var converted = f.ConvertToMeasure(concreteType); 
} 

public class A: Iload 
{ 
    // something 
} 

public class B: ILoad 
{ 
    //Something 
} 

public class Factory 
{ 
    public List<Measure> ConvertToMeausre(A model) 
    { 
     return some List<Measure> 
    } 

    public List<Measure> ConvertToMeausre(B model) 
    { 
     return some List<Measure> 
    } 
} 
+0

太棒了! – Devsined 2014-09-05 17:38:43

0

我只是將ConvertToMeasure移動到您的界面。

interface ILoad { 
    List<Measure> ConvertToMeasure(); 
} 

class A : ILoad { 
    public string PropA { get; set; } 


    public List<Measure> ConvertToMeasure() 
    { 
     throw new NotImplementedException(); 
    } 
} 

class B : ILoad { 
    public string PropB { get; set; } 


    public List<Measure> ConvertToMeasure() 
    { 
     throw new NotImplementedException(); 
    } 
} 

那麼你可以訪問類,通常:

    List<ILoad> list = new List<ILoad>(); 

     var s = new A(); 
     list.Add(new A() { PropA = "test1" }); 
     list.Add(new B() { PropB = "test2" }); 
     list.Add(new A() { PropA = "test3" }); 



     foreach (var item in list) 
     { 
      item.ConvertToMeasure(); 
     } 

這是不是你能做什麼呢?

+0

我想調用一個識別對象類型的工廠。我在帖子 – Devsined 2014-09-05 17:21:53

+0

上添加了更多細節......由於您已經定義了一個界面,我認爲解決方案是將ConvertToMeasure移動到您的界面。 公共類答:Iload的 {// 東西 } publicclass B:I負荷 {// 東西 } – Rgwan 2014-09-05 17:25:09

0

你的情況,你可以把所有的反射式相關的代碼轉換成特殊函數,它ILoad,並進一步對其進行處理:

public class Factory 
{ 
    public IList<Measure> ConvertToMeasures(ILoad load) 
    { 
     if (load == null) 
      throw new NullArgumentException("load"); 

     if (load is A) 
      return ConvertToMeausre((A)load); 

     if (load is B) 
      return ConvertToMeausre((B)load); 

     throw new NotSupportedException(); 
    } 

    public List<Measure> ConvertToMeausre(A model) 
    { 
     return some List<Measure> 
    } 

    public List<Measure> ConvertToMeausre(B model) 
    { 
     return some List<Measure> 
    } 
} 

,只是在的foreach使用它ILoad,因爲轉換對混凝土沒有依賴性類型ILoad

foreach (var item in list) 
{ 
    var converted = f.ConvertToMeasure(item); 
} 

這不是最好的解決辦法,但如果你已經降級的具體類型接口,你不能改變他們,這是最簡單的一種。


當然更OOP般的解決辦法是修改ILoad接口,但正如你所說這是不可能的。然而,如果將大大簡化了使用場景,你可以創建自己的擴展接口和特定包裝每個I負荷實施者:

public interface ILoadExt: ILoad 
{ 
    IList<Measure> ConvertToMeasure(); 
} 


public class AExt : A, ILoadExt 
{ 
    public List<Measure> ConvertToMeasure() 
    { 
     return some List<Measure> 
    } 
} 

public class BExt : B, ILoadExt 
{ 
    public List<Measure> ConvertToMeasure() 
    { 
     return some List<Measure> 
    } 
} 

和包裝物品,當你讓他們:

var load = new BExt(factory.GetB()); 
IList<ILoadExt> loads = new List<ILoadExt>(); 
loads.Add(load); 
+0

我試圖避免這種情況的解決方案,因爲我需要每一個我需要時間來violiate OCP原則添加一個新類如D類 – Devsined 2014-09-05 17:30:33

+0

@Devsined如果您的邏輯是依賴於類型的(對於A返回XX,對於B返回YY),那麼唯一的解決方案是將類型的知識嵌入到處理函數中,或者更改現有的類型在本地支持這種功能。 – 2014-09-05 17:36:07