返回根和最高级父级的分层列表

时间:2017-02-17 15:24:07

标签: c# linq

我正在尝试构建一个基本的依赖注入容器,让自己更好地理解它们的工作方式。我的容器的一个部分是将别名映射到类名。然后可以递归地映射该类以生成分层列表。它还必须处理映射到自身的情况。

例如说我有以下映射:

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");

两个变量都会返回一个名为&#34; foo&#34;的新Map。和班级&#34; Foo&#34;。这是另一个进一步解释的例子。鉴于以下地图:

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

它将生成一个名为&#34; foo&#34;的新地图。和班级&#34; FooExtended&#34;。

这是我的第一次尝试:

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);
    }
}

这正确地返回了具有两个示例的正确类的Map。但是返回的名字是&#34; Foo&#34;对于这两个例子。这应该是&#34; foo&#34;因为这是层次结构的根源。

我希望我已经解释得那么好了。如果有人能告诉我我做错了什么,我会很感激。感谢

1 个答案:

答案 0 :(得分: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将返回最高类型的名称(EG,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”。

希望有所帮助。