ana*_*der 5 c# dictionary this
这有点奇怪.
我正在构建一个Web应用程序,我正在整理一个简单的工厂模式,以处理一些对象实例化.我不喜欢丑陋的开关盒块,所以我倾向于这样做:
public enum Option
{
Option1,
Option2,
Option3
}
public Dictionary<Option, Func<MyBaseClass>> OptionMapping
= new Dictionary<Option, Func<MyBaseClass>>
{
{ Option1, () => new DerivedClassOne() },
{ Option2, () => new DerivedClassTwo() },
{ Option3, () => new DerivedClassThree() }
};
Run Code Online (Sandbox Code Playgroud)
然后开关块变为MyBaseClass selectedThing = OptionMapping[currentOption]();.
在我编写这段代码时,我想到如果你遇到过两个选项需要相同动作的情况,你最终会Func<>在两个地方找到相同的结果,我宁愿避免.假设目前你不能只重构一些逻辑来将这两个选项合并为一个,我想知道是否有办法让一个Func人调用另一个.
我的第一个想法是:
public Dictionary<Option, Func<MyBaseClass>> OptionMapping
= new Dictionary<Option, Func<MyBaseClass>>
{
{ Option1, () => new DerivedClassOne() },
{ Option2, () => new DerivedClassTwo() },
{ Option3, () => this[Option1]() }
};
Run Code Online (Sandbox Code Playgroud)
但LINQPad中的一个快速测试告诉我,这不起作用,因为当然是this指编写代码的类,而不是Dictionary(显然我花了太多时间在this更加变幻无常的语言中).我的第二个想法是将其更改为() => OptionMapping [Option1](),但这会产生一个错误,您在OptionMapping初始化之前尝试使用它.你当然可以这样做:
public Dictionary<Option, Func<MyBaseClass>> OptionMapping
= new Dictionary<Option, Func<MyBaseClass>>
{
{ Option1, () => new DerivedClassOne() },
{ Option2, () => new DerivedClassTwo() }
};
OptionMapping.Add(Option3, () => OptionMapping [Option1]());
Run Code Online (Sandbox Code Playgroud)
哪个有效,但不是那么漂亮.所以,这个问题主要是好奇心.
有没有办法Dictionary从另一个访问一个元素?更一般地,不C#有这样一个关键词this,意思是"我在里面的对象,现在,而不是"在写入时包含的对象"在执行时"?
编辑:
最初,它Dictionary是静态的,所以我提到的关于在它初始化之前使用它的错误不会发生.这static实际上是从更大的代码块中粘贴并编辑它,然后复制粘贴错误的剩余部分.
因此,发布的主要答案是有一个单独的对象来存储Func,然后将其添加到Dictionary两次.这是有道理的,并且或多或少与我最终的结果(由于各种原因,它也使一些周围的代码更清洁)但它有点避免我最感兴趣的问题的一部分,是否可以在C#中访问您在运行时所在的对象,以便对象可以访问它们当前所在的字典(或列表或数组等).
这应该有效:
private static Dictionary<Option, Func<MyBaseClass>> OptionMapping
= new Dictionary<Option, Func<MyBaseClass>> {
{ Option.Option1, () => new DerivedClassOne() },
{ Option.Option2, () => new DerivedClassTwo() },
{ Option.Option3, () => OptionMapping[Option.Option2]() }
};
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是Option3包含一个不同的 对象,该对象每次调用它时都Func依赖另一个对象来生成其输出。Func
我认为这不如显式创建共享Func对象并将其多次放入字典中的解决方案(即您的第二个代码片段或下面的替代方案)
private static Dictionary<Option, Func<MyBaseClass>> OptionMapping;
static MyClass() {
Func<MyBaseClass> makeDerivedTwo = () => new DerivedClassTwo();
OptionMapping = new Dictionary<Option, Func<MyBaseClass>> {
{ Option.Option1, () => new DerivedClassOne() },
{ Option.Option2, makeDerivedTwo },
{ Option.Option3, makeDerivedTwo }
};
}
Run Code Online (Sandbox Code Playgroud)