1

长话短说,我正在创建一个看起来有点像这样的工厂:

    public static ITag GetByTagName(string tagName)
    {
        tagName = tagName.ToLower();
        switch (tagName)
        {
            case "devicevar":
                return new DeviceVar();
            case "devicefilter":
                return new DeviceFilter();
        }
        return null;
    }

但我还需要一种方法来检查是否tagName对应于 ITag。本质上,我正在检查是否GetByTagName会在不实际运行的情况下返回 null:

private List<string> tagNames = new List<string> { "devicevar", "devicefilter" };

public static bool IsValidTagName(string tagName)
{
    return tagName.Contains(tagName);
}

看看我们那里有一些丑陋的重复吗?我不想指定可能的值tagName两次。我总是可以更改我的方法,以便它使用工厂尝试并实例化一个 ITag,如果它返回 null,那么我知道它不是有效值。但这似乎很浪费:

public static bool IsValidTagName(string tagName)
{
    return GetByTagName(tagName) != null;
}

一定会有更好的办法

笔记:

我有一个很好的(虽然冗长的)理由需要进行这项检查,但事实并非如此

“如果我给它这个字符串,GetByTagName 会返回一个 ITag 吗?是的?好的,调用 GetByTagName”

4

2 回答 2

1

您可以创建类型字典Dictionary<string, Type>,将标签类型映射到它们的名称。

Dictionary<string, Type> tags = new Dictionary<string, Type>() {
    { "devicevar", typeof(DeviceVar) },
    { "devicefilter", typeof(DeviceFilter) }
};

用于ContainsKey检查名称是否有效:

public static bool IsValidTagName(string tagName)
{
    return tags.ContainsKey(tagName);
}

使用 Activator 创建实例:

public static ITag GetByTagName(string tagName)
{
    tagName = tagName.ToLower();

    if (!IsValidTagName(tagName))
        throw new ArgumentException(); // or return null

    return (ITag)Activator.CreateInstance(tags[tagName]);
}

更新(为了性能)而不是将类型存储在字典中,将创建方法存储在那里:

var tagsFactory = new Dictionary<string, Func<ITag>>() {
    { "devicevar", _ => new DeviceVar() },
    { "devicefilter", _ => new DeviceFilter() }
};

获取标签将如下所示:

return tagsFactory[tagName]();
于 2013-08-27T10:05:59.127 回答
0

如果tagName始终匹配 TypeName,则可以不使用任何字典并像这样简单地编写

    public static ITag GetByTagName(string tagName)
    {
        var type = typeof(ITag).Assembly.GetTypes().SingleOrDefault(t => string.Equals(t.Name, tagName, StringComparison.OrdinalIgnoreCase));
        if (type == null)
            return null;
        return (ITag) Activator.CreateInstance(type);
    }

    public static bool IsValidTagName(string tagName)
    {
        return GetByTagName(tagName) != null;
    }

如果您的类不在同一个程序集中,您应该修复一些此代码。

这种替代方法的优点是它适用于程序集中的任何类,您不需要在任何地方枚举它们

于 2013-08-27T10:22:02.297 回答