字典<X,Func <Y >>从其中的Func <>访问包含的Dictionary

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#中访问您在运行时所在的对象,以便对象可以访问它们当前所在的字典(或列表或数组等).

das*_*ght 2

这应该有效:

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)

ideone 上的演示。

这种方法的问题是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)