2017-02-17 8 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». Вот еще один пример для дальнейшего объяснения. На следующей карте:

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

Это создаст новую карту с именем «foo» и классом «FooExtended».

Вот моя первая попытка:

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) вдоль всего пути выполнения

EDIT - Это не полное решение, но я ухожу it

Я переименовал параметры в своем тесте, чтобы мне было легче читать, извините.

Весь мой 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); 
    } 
} 

EDIT СНОВА - Фактический ответ, основанный на комментарии

Окончательный ответ, GetMap возвратит имя самого высокого типа (например, foo) и класс самый низкий (ЭГ 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» для имени и «FooExtended» для класса – Carson

+0

Я получаю это, когда говорю «GetMap» (карта «foo»), но когда я говорю «GetMap» (карта «Foo»), он не признает, что «Foo "имеет родителя" foo ". Возможно, мое имя могло быть лучше. – nfplee