我有一个Factory类,我根据字符串匹配实例化类。
示例代码段:
[dbo].[BookOrder](
[OrderId] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[OrderNo] [numeric](18, 0) NOT NULL,
[OrderDate] [datetime] NULL,
[OrderRetailerId] [int] NULL,
[OrderDistributorId] [int] NULL,
[OrderAgentId] [int] NULL,
[OrderTotalItems] [float] NULL,
[OrderTotalBaseAmt] [float] NULL,
[OrderTaxTotal] [float] NULL,
[OrderTotal] [float] NULL,
[OrderRemark] [varchar](150) NULL,
[OrderSMSStat] [bit] NULL,
[OrderCreatedById] [int] NULL,
[OrderCreatedOrigin] [varchar](50) NULL,
[OrderDeactivate] [bit] NULL,
[CmpId] [int] NULL,
但现在我想匹配少量模式(文件路径),然后根据匹配的模式实例化类。
所以我的问题是我在哪里可以存储我想要匹配的这些模式? 它们应该在我的数据库中的“表”中吗?或者我可以在这里有一个哈希表(当任何一个模式匹配时,它映射到要实例化的类)?
答案 0 :(得分:3)
首先,您的Create
方法实际上并没有创建任何内容。它返回已创建的实例。每次调用Create
都会返回相同的实例。
如果那是你想要的,那很好,但是如果你每次想要一个新实例,我可以提出建议吗?而不是存储对象,存储一个返回新对象的函数:
class Factory
{
Dictionary<string,Func<ICreate>> test = new Dictionary<string,Func<ICreate>>();
public Factory()
{
test.Add( "classA", () => new a() );
test.Add( "classB", () => new b() );
test.Add( "classC", () => new c() );
}
public ICreate Create(string toMatch)
{
var creationFunction = test[toMatch];
return creationFunction();
}
}
看看它是如何工作的? lambda表达式() => new a()
可以像函数一样调用,并且每次调用都会实例化一个新的a
。
对于模式匹配,你可以做类似的事情。我们为函数设置了一个函数;现在让我们把钥匙放进去。我们将存储一个接受字符串并返回布尔值的函数,而不是存储字符串。然后我们要做的就是搜索第一个字典条目,执行该键返回true。
class Factory
{
Dictionary<Func<string,bool>,Func<ICreate>> _map = new Dictionary<Func<string,bool>, Func<ICreate>>();
public Factory()
{
_map.Add
(
a => a.Contains("classA"),
() => new a()
);
_map.Add
(
a => a.Contains("classB"),
() => new b()
);
_map.Add
(
a => a.Contains("classC"),
() => new c()
);
}
public ICreate Create(string toMatch)
{
var func = _map.Where( e => e.Key(toMatch) ).First().Value;
return func();
}
}
public class Program
{
static public void Main()
{
var f = new Factory();
var o = f.Create("c:\folder\subfolder\classA");
Console.WriteLine("You just created an instance of '{0}'.", o.GetType().Name);
}
}
输出:
You just created an instance of 'a'.
在这个例子中,我们与Contains()
进行了模式匹配,但由于它是Func,你可以使用任何字符串函数,正则表达式来编写你想要的任何表达式。你也可以混搭;例如,您可以使用正则表达式来标识需要ClassA的模式,但您可以使用常规==
比较来标识ClassB的模式。此外,如果要确保提交的任何字符串都匹配一个且只有一个模式,我们可以将LINQ函数从First
更改为Single
。