从交换机/案例中获取案例列表以在验证方法中使用

时间:2013-08-27 10:02:28

标签: c# factory-pattern

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

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

必须有更好的方法

注意:

我有一个好的(albiet longwinded)理由需要进行此检查,而且它不是

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

2 个答案:

答案 0 :(得分: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]);
}

UPDATE(用于性能)不是在字典中存储类型,而是在那里存储创建方法:

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

获取标签看起来像:

return tagsFactory[tagName]();

答案 1 :(得分: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;
    }

如果你的作品不在同一个装配中,你应该修改一下这段代码。

这个替代方案的优点是它可以与assebmly中的任何类一起使用,而且你不需要在任何地方枚举它们