2014-10-08 44 views
-1

重構方法,我們與.NET Framework 3.5的,誰像下面的人做了一些類:帶班implenting的IList <T>

public class A 
{ 
    public override string ID { get; set; } 
    public override string Name { get; set; } 
    private List<B> versionen = new List<B>(); 
    public List<B> Versionen 
    { 
     get { return versionen; } 
     set { versionen = value; } 
    } 
} 

在其他類所使用的方法,如

private static void DoSomething(List<A> versioningObj) 
{ 
    foreach (A concretClassAObject in versioningObj) 
    { 
     foreach (B concretClassAVersionObject in concretClassAObject.Versionen) 
     { 
     } 
    } 
} 

要重構此代碼並開發一種常用方法,我嘗試實現以下接口:

public interface VersioningObject<T> : IIDIdentifiable where T : IIDIdentifiable 
{ 
    string Name { get; set; } 
    List<T> Versionen { get; set; } 
} 

public interface IIDIdentifiable 
{ 
    string ID { get; set; } 
} 

A類實現'VersioningObject',B類實現'IIDDIdentifiable'。新的方法是這樣的:

private static void DoSomething(List<VersioningObject<IIDIdentifiable>> versioningObj) 
{ 
    foreach (VersioningObject<IIDIdentifiable> concretClassAObject in versioningObj) 
    { 
     foreach(IIDIdentifiable concretClassAVersionObject in concretClassAObject.Versionen) { 
     } 
    } 
} 

我嘗試調用此方法 'DoSomething的',如:

List<A> myList = new List<A>() {new A()}; 
DoSomething(myList); 

,並得到了以下錯誤:

  • 不能轉換「系統.Collection.Generic.List「更改爲」System.Collection.Generic.List>「
    • 對於DoSomeThing最佳重載的方法匹配(System.Col lections.Generic.List>)有一些無效參數

我怎麼能解決這個問題。非常感謝您提前!

+0

你的問題沒有意義。首先什麼是'B'?其次,'DoSomething'具有void返回類型? – DavidG 2014-10-08 08:36:23

+0

爲什麼通用'VersioningObject '如果您將'T'限制爲'IIDIdentifiable'?爲什麼不讓'VersioningObject'有一個'List Versionen'? – Corak 2014-10-08 08:48:18

+0

Btw。標題有點誤導。沒有一個班正在實施'IList '。 – Corak 2014-10-08 08:53:56

回答

0

ListVersioningObject都不是關於它們的通用參數的協變。因爲這個VersioningObject<Child>不能隱式轉換爲VersioningObject<Parent>(其中Child延伸Parent)。即使它(當前它不能協變,因爲它接受通用參數作爲輸入),那麼List<VersioningObject<Child>>仍不會隱式轉換爲List<VersioningObject<Parent>>

要做到這一切,你需要做出幾個相當基本的重構。

1)VersioningObject將只需要揭露如何讀取值,而不是給他們寫信,從而使其成爲概念協:

public interface VersioningObject<out T> : IIDIdentifiable where T : IIDIdentifiable 
{ 
    string Name { get; } 
    List<T> Versionen { get; } 
} 

2)DoSomething將需要接受IEnumerable,而不是ListIEnumerable是協變的,因爲它只允許使用泛型參數讀取數據。 DoSomething只需要在你顯示的內容中迭代數據,所以這應該就好了。如果您需要實際使用List特定成員,那麼這根本不可能。

private static void DoSomething(
    IEnumerable<VersioningObject<IIDIdentifiable>> versioningObj) 
{ 
    //... 
} 

另外通用的協方差只加在.NET 4.0中,所以你需要使用該版本的框架,對於任何這是一個選項。