gpt4 book ai didi

c# - 如何使用枚举解析类类型

转载 作者:太空狗 更新时间:2023-10-29 23:10:00 25 4
gpt4 key购买 nike

我的项目中有一组类(遵循策略模式)。在 main 函数中,我从服务器接收一个枚举值,并基于它创建一个基类类型的对象。

我正在使用 switch/case 语句来实现这一点。我在某处读到,Open/Closed 原则不允许在添加新类时打开函数来添加新的 case 语句。

我正在考虑使用 Activator.CreateInstance()。有什么缺点吗?

有没有其他方法可以从枚举类型创建对象?

在下面添加示例,即使它不是一个完整的策略模式

abstract public class Mammal
{
public abstract void MakeSound()
}

class Cat:Mammal
{
public override void MakeSound()
{
Console.WriteLine("Meow");
}
}

class Dog:Mammal
{

public override void MakeSound()
{
Console.WriteLine("Bow");
}
}

Main()
{

MammalTypes mammalType = RecieveValueFromServer();
Mammal mammalBase
switch(mammalType) // need to make this dynamic depending upon Enum type
{
case MammalTypes.Cat:mammalBase = new Cat()
break;
case MammalTypes.Dog:mammalBase = new Dog()
break;
}

mammalBase.MakeSound()
}

最佳答案

实现真正 OCP 的一种方法可能如下:

定义一个抽象方法 Is 来强制 Mammal 的每个具体子类型指定它是否适合给定的枚举值:

abstract public class Mammal
{
public abstract void MakeSound();

public abstract bool Is(MammalTypes mammalType);
}

Is 在子类中的实现如下所示:

class Cat : Mammal
{
// other specific members

public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Cat;
}
}

class Dog : Mammal
{
// other specific members

public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Dog;
}
}

完成后,我们现在可以创建一个 MammalFactory 类,当给定一个 Mammal 枚举值时,它会扫描可用的类,并在找到匹配项时返回该类的一个实例:

public class MammalFactory
{
private readonly IEnumerable<Type> _mammalTypes;

public MammalFactory()
{
var currentAssembly = Assembly.GetExecutingAssembly();

_mammalTypes = currentAssembly.GetTypes()
.Where(t => typeof(Mammal).IsAssignableFrom(t) && !t.IsAbstract);
}

public Mammal Create(MammalTypes mammalType)
{
return _mammalTypes
.Select(type => CreateSpecific(type, mammalType))
.First(mammal => mammal != null);
}

public Mammal CreateSpecific(Type type, MammalTypes mammalEnumType)
{
var mammalInstance = (Mammal)Activator.CreateInstance(type);

return mammalInstance.Is(mammalEnumType) ? mammalInstance : null;
}
}

最终的用法是这样的:

var mammalFactory = new MammalFactory();

var guessWhatMammal = mammalFactory.Create(MammalTypes.Cat);

这完全符合 OCP。只需要创建一个新的 Mammal 类,它就可以自动连接并准备好在应用程序中使用。 (无需修改应用程序中的任何其他内容,除了枚举本身)

这种方法存在一些问题:

  • 它只扫描当前正在执行的程序集以查找哺乳动物类型
  • 每次需要测试该类型是否合适时,它都必须创建一个 Mammal 实例

虽然可以解决这些问题,但仍然存在一个问题:复杂性

这很复杂,因为:

  • 我们将所需的代码量增加了一倍
  • 自动连接可能会让刚接触该项目的人感到困惑

我想结论是这样的:设计模式并不是严格的规则。仅仅为了符合给定的设计而做某事是不值得的。相反,我们必须务实,并在模式一致性和实用性/简单性/可读性之间找到完美的平衡。这在很大程度上取决于我们试图解决的问题,在许多情况下,它很可能是您在问题中提出的 switch 语句。

关于c# - 如何使用枚举解析类类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8959606/

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