这是一个有点奇怪的问题。
我正在构建一个Web应用程序,并且正在组合一个类似于工厂模式的东西来处理一些对象实例化。我不喜欢笨重的switch-case语句,所以我倾向于这样做:
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() }
};
然后,switch块变成了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]() }
};
但是在 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]());
虽然这个方法能用,但看起来不太美观。所以,这个问题主要是出于好奇。
有没有一种方法可以从一个Dictionary
中访问另一个元素?更普遍地说,C#是否有一个关键字像this
,表示“我此刻正在执行的对象”,而不是“编写时的包含对象”?
编辑:
最初,该Dictionary
是静态的,所以我提到的在初始化之前使用它的错误不会发生。实际上,static
实际上是从粘贴较大代码块并对其进行编辑,然后复制粘贴错误的结果。
因此,主要回答是关于创建一个单独的对象来存储Func
,然后将其添加到Dictionary
两次。这很有道理,也更或多或少是我最终采取的方法(由于各种原因,它还使周围的代码更加清洁),但它有点回避了我最感兴趣的部分,即在C#中是否可以在运行时访问你所在的对象,以便对象可以访问它们当前所在的字典(或列表、数组等)。