2017-02-17 49 views
1

我正在嘗試構建基本的依賴注入容器,以便更好地瞭解它們的工作原理。我的容器的一個部分是將別名映射到類名。然後可以遞歸地映射這個類來產生分層列表。它還必須處理它映射到自身的情況。返回根目錄和最高級別父級的分層列表

例如說我有以下映射:

var map = new List<Map>() { 
    { new Map("Foo", "Foo") }, 
    { new Map("foo", "Foo") } 
}; 

其中地圖是:

public class Map { 
    public string Name { get; set; } 
    public string Class { get; set; } 

    public Map(string name, string @class) { 
     Name = name; 
     Class = @class; 
    } 
} 

我想寫一個方法(GetMap操作),這將返回根(名稱)和給定名稱的最高級別父級(類)。例如我說:

var map = GetMap(map, "Foo"); 
var map2 = GetMap(map, "foo"); 

這兩個變量都會返回一個名爲「foo」和類「Foo」的新Map。這是另一個進一步解釋的例子。鑑於以下地圖:

var map = new List<Map>() { 
    { new Map("Foo", "FooExtended") }, 
    { new Map("foo", "Foo") } 
}; 

它會產生一個名爲「foo」和類「FooExtended」的新的Map。

這是我第一次嘗試:

private Map GetMap(List<Map> map, string @class, string name = null) { 
    var item = map.SingleOrDefault(m => m.Name == @class); 

    if (item != null && @class != item.Class) { 
     return GetMap(map, item.Class, @class); 
    } else { 
     return new Map(name ?? @class, @class); 
    } 
} 

這正確返回與這兩個例子正確的類的地圖。但是,對於這兩個示例,返回的名稱都是「Foo」。這應該是「foo」,因爲它是層次結構的根源。

我希望我解釋得很好。如果有人能告訴我我做錯了什麼,我會很感激。由於

+0

這對你有幫助嗎? – Carson

回答

1

試試這個

public Map GetMap(List<Map> map, string name, string finalName = null) { 
    var item = map.SingleOrDefault(m => m.Name == name); 

    if (item != null && name != item.Class) { 
     return GetMap(map, item.Class, finalName ?? name); // <- for you, name ?? @class 
    } else { 
     return new Map(finalName ?? name, name); 
    } 
} 

您需要通過name(或在我的情況finalName)在整個執行路徑

編輯 - 這是不是一個完整的解決方案,但我要離開它

我在我的測試中重新命名參數,所以我更容易閱讀,對此感到抱歉。

我的整個LinqPad代碼

void Main() 
{ 
    var map = new List<Map>() { 
     { new Map("FooExtended", "FooExtended2") }, 
     { new Map("Foo", "FooExtended") }, 
     { new Map("foo", "Foo") } 
    }; 

    var newMap = GetMap(map, "foo"); 
    newMap.Dump(); // Gives Map("foo", "FooExtended2") 
} 

public class Map { 
    public string Name { get; set; } 
    public string Class { get; set; } 

    public Map(string name, string @class) { 
     Name = name; 
     Class = @class; 
    } 
} 

private static Map GetMap(List<Map> map, string name, string finalName = null) { 
    var item = map.SingleOrDefault(m => m.Name == name); 

    if (item != null && name != item.Class) { 
     return GetMap(map, item.Class, finalName ?? name); 
    } else { 
     return new Map(finalName ?? name, name); 
    } 
} 

再次編輯 - 基於評論實際答案

最終答案,GetMap將返回最高的類型(例如,foo)的名稱和類的最低(EG Foo

private static Map GetMap(List<Map> map, string name) { 
    return new Map(GetMapName(map, name), GetMapClass(map, name)); 
} 

private static string GetMapName(List<Map> map, string name) { 
    var item = map.SingleOrDefault(m => m.Name != name && m.Class == name); 

    return item != null ? GetMapName(map, item.Name) : name; 
} 

private static string GetMapClass(List<Map> map, string name) { 
    var item = map.SingleOrDefault(m => m.Name == name && m.Class != name); 

    return item != null ? GetMapClass(map, item.Class) : name; 
} 

我用了我上面發佈的代碼,無論我使用什麼名稱或類,我都會得到「foo」,「FooExtended2」。

希望有所幫助。

+0

謝謝,我更喜歡你的命名。不幸的是它產生了相同的結果。 – nfplee

+0

我爲名稱獲得「foo」,爲 – Carson

+0

獲得「FooExtended」當我說GetMap(map,「foo」)但是當我說GetMap(map,「Foo」)時,它不會承認「Foo 「有一個」foo「的父母。也許我的命名可能會更好。 – nfplee