gpt4 book ai didi

c# - 基于读取输入input实例化子类

转载 作者:行者123 更新时间:2023-11-30 21:30:57 24 4
gpt4 key购买 nike

我为了能够从另一个项目读取文件,我正在复制写入代码并根据需要进行调整。

我遇到了一个看起来真的很丑的 curios 构造,但我不知道是否有其他方法可以处理它。

代码看起来像这样:

int type = reader.readInt32():
BaseClass p = BaseClass.Instantiate((BaseClassEnum)type);
object.Read(reader);

这段代码看起来不错,确实如此,但是 BaseClass.Instantiate(BaseClassEnum type) 方法还有一些不足之处。

基本上,它是一个巨大的 switch case 语句,根据传递的类型参数实例化基类的子类。

这里有什么方法可以避免 switch case 吗?我可以创建一个字典,将 BaseClassEnum 映射到某种允许我调用它的构造函数的类引用吗?像这样的东西:

Dictionary<int, ???> bindings = new Dictionary<int, ???>(){
{BaseClassEnum1, SubClass1},
{BaseClassEnum2, SubClass2}
}

//...

//Assuming SubClass1 has a constructor SubClass1()
BaseClass p = new bindings[BaseClassEnum1]();

//I could even create a new constructor SubClass(BinaryReader reader) and do
BaseCoass p = new bindings[BaseClassEnum1](reader);

最后,代码看起来像这样:

BaseClass p = new bindings[(BaseClassEnum)reader.ReadInt32()](reader);

最佳答案

类/类型工厂(即您正在创建的)以四种基本方式之一实现。

  1. Switch 语句或等效语句或一系列 if/then/else 语句
  2. 允许将值映射到特定类型的字典或其他结构
  3. 按名称调用的一些变体(在 C# 中表示反射)
  4. 事件订阅(不经常使用)可能会在内部使用其他方法之一。

Switch 语句很丑陋,当然也容易出错,字典也很丑陋,也有自己的错误,但更容易测试。反射通常较慢,事件订阅更慢。

所以,没有 Elixir 。

你所描述的看起来像:

var binding = new Dictionary<int, Func<BaseClass>>(){{BaseClassEnum1, ()=> new SubClass1()},
{BaseClassEnum2, ()=>new SubClass2()}};


var p = new bindings[BaseClassEnum1]();

工作示例 https://dotnetfiddle.net/rWwCjw (变量名称略有不同)。

我应该注意到上面和示例都有些简化,特别是如果这应该涵盖应用程序中所有可能的子类,字典应该是它自己的属性/函数,以便您可以测试 (通过反射)你的应用程序中的所有子类都出现在列表中。

关于c# - 基于读取输入input实例化子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53896120/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com