Enum 是这里的正确方法吗?

发布于 2024-07-22 20:48:46 字数 1103 浏览 3 评论 0原文

我不确定我是否在这里滥用枚举。 也许这不是最好的设计方法。

我有一个枚举,它声明了执行批处理文件的方法的可能参数。

public enum BatchFile
{
    batch1,
    batch2
}

然后我就有了我的方法:

public void ExecuteBatch(BatchFile batchFile)
{
    string batchFileName;
    ...
    switch (batchFile)
        {
            case BatchFile.batch1:
                batchFileName = "Batch1.bat";
                break;
            case BatchFile.batch2:
                batchFileName = "Batch2.bat";
                break;
            default:
                break;
        }
    ...
    ExecuteBatchFile(batchFileName);
}

所以我想知道这是否是声音设计。

我想到的另一个选择是创建一个 Dictionary<> 在这样的构造函数中:

Dictionary<BatchFile, String> batchFileName = new Dictionary<BatchFile, string>();
batchFileName.Add(BatchFile.batch1, "batch1.bat");
batchFileName.Add(BatchFile.batch2, "batch2.bat");

然后我不使用 switch 语句,而是直接去:

public void ExecuteBatch(BatchFile batchFile)
{
    ExecuteBatchFile(batchFileName[batchFile]);
}

我猜后者是更好的方法。

I'm not sure if I am abusing Enums here. Maybe this is not the best design approach.

I have a enum which declares the possible parameters to method which executes batch files.

public enum BatchFile
{
    batch1,
    batch2
}

I then have my method:

public void ExecuteBatch(BatchFile batchFile)
{
    string batchFileName;
    ...
    switch (batchFile)
        {
            case BatchFile.batch1:
                batchFileName = "Batch1.bat";
                break;
            case BatchFile.batch2:
                batchFileName = "Batch2.bat";
                break;
            default:
                break;
        }
    ...
    ExecuteBatchFile(batchFileName);
}

So I was wondering if this is sound design.

Another option I was thinking was creating a Dictionary<> in the constructor like this:

Dictionary<BatchFile, String> batchFileName = new Dictionary<BatchFile, string>();
batchFileName.Add(BatchFile.batch1, "batch1.bat");
batchFileName.Add(BatchFile.batch2, "batch2.bat");

Then instead of using a switch statement I would just go:

public void ExecuteBatch(BatchFile batchFile)
{
    ExecuteBatchFile(batchFileName[batchFile]);
}

I'm guessing the latter is the better approach.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

伪心 2024-07-29 20:48:46

我可能会按照这些思路进行设计:

public interface IBatchFile
{
    void Execute();
}

public class BatchFileType1 : IBatchFile
{
    private string _filename;

    public BatchFileType1(string filename)
    {
        _filename = filename;
    }

    ...

    public void Execute()
    {
        ...
    }
}

public class BatchFileType2 : IBatchFile
{
    private string _filename;

    public BatchFileType2(string filename)
    {
        _filename = filename;
    }

    ...

    public void Execute()
    {
        ...
    }
}

事实上,我会将所有常见功能提取到 BatchFile 基类中

I'd probably go for a design along these lines:

public interface IBatchFile
{
    void Execute();
}

public class BatchFileType1 : IBatchFile
{
    private string _filename;

    public BatchFileType1(string filename)
    {
        _filename = filename;
    }

    ...

    public void Execute()
    {
        ...
    }
}

public class BatchFileType2 : IBatchFile
{
    private string _filename;

    public BatchFileType2(string filename)
    {
        _filename = filename;
    }

    ...

    public void Execute()
    {
        ...
    }
}

In fact, I'd extract any common functionality into a BatchFile base class

策马西风 2024-07-29 20:48:46

如果您突然需要第三个批处理文件怎么办? 你必须修改你的代码,重新编译你的库,每个使用它的人都必须做同样的事情。

每当我发现自己编写的魔术字符串可能会发生变化时,我都会考虑将它们放入额外的配置文件中,将数据保留在代码之外。

What if you suddenly need a third batch file? You have to modify your code, recompile your library and everybody who uses it, has to do the same.

Whenever I find myself writing magic strings that might change, I consider putting them into an extra configuration file, keeping the data out of the code.

樱娆 2024-07-29 20:48:46

在这种情况下,我个人会使用静态常量类:

public static class BatchFiles
 { 
   public const string batch1 = "batch1.bat";
   public const string batch2 = "batch2.bat"; 
 }

I would personally use a static class of constants in this case:

public static class BatchFiles
 { 
   public const string batch1 = "batch1.bat";
   public const string batch2 = "batch2.bat"; 
 }
只怪假的太真实 2024-07-29 20:48:46

如果您想使用枚举,那么您可能需要考虑利用属性,以便可以针对元素存储附加信息(例如文件名)。

下面是一些示例代码,演示如何声明属性:

using System;

public enum BatchFile
{
    [BatchFile("Batch1.bat")]
    batch1,
    [BatchFile("Batch2.bat")]
    batch2
}

public class BatchFileAttribute : Attribute
{
    public string FileName;
    public BatchFileAttribute(string fileName) { FileName = fileName; }
}

public class Test
{
    public static string GetFileName(Enum enumConstant)
    {
        if (enumConstant == null)
            return string.Empty;

        System.Reflection.FieldInfo fi = enumConstant.GetType().GetField(enumConstant.ToString());
        BatchFileAttribute[] aattr = ((BatchFileAttribute[])(fi.GetCustomAttributes(typeof(BatchFileAttribute), false)));
        if (aattr.Length > 0)
            return aattr[0].FileName;
        else
            return enumConstant.ToString();
    }
}

要获取文件名,只需调用:

string fileName = Test.GetFileName(BatchFile.batch1);

If you want to use an enum then you may want to consider utilising attributes so you can store additional inforation (such as the file name) against the elements.

Here's some sample code to demonstrate how to declare the attributes:

using System;

public enum BatchFile
{
    [BatchFile("Batch1.bat")]
    batch1,
    [BatchFile("Batch2.bat")]
    batch2
}

public class BatchFileAttribute : Attribute
{
    public string FileName;
    public BatchFileAttribute(string fileName) { FileName = fileName; }
}

public class Test
{
    public static string GetFileName(Enum enumConstant)
    {
        if (enumConstant == null)
            return string.Empty;

        System.Reflection.FieldInfo fi = enumConstant.GetType().GetField(enumConstant.ToString());
        BatchFileAttribute[] aattr = ((BatchFileAttribute[])(fi.GetCustomAttributes(typeof(BatchFileAttribute), false)));
        if (aattr.Length > 0)
            return aattr[0].FileName;
        else
            return enumConstant.ToString();
    }
}

To get the file name simply call:

string fileName = Test.GetFileName(BatchFile.batch1);
北方的巷 2024-07-29 20:48:46

我认为后一种方法更好,因为它分离了关注点。 您有一个专门用于将枚举值与物理路径关联的方法和一个用于实际执行结果的单独方法。 第一次尝试稍微混合了这两种方法。

不过我认为使用 switch 语句来获取路径也是一种有效的方法。 枚举在很多方面都意味着可以切换。

I think the latter approach is better because it separates out concerns. You have a method which is dedicated to associating the enum values with a physical path and a separate method for actually executing the result. The first attempt mixed these two approaches slightly.

However I think that using a switch statement to get the path is also a valid approach. Enums are in many ways meant to be switched upon.

伤感在游骋 2024-07-29 20:48:46

如果您不需要在不重新编译/重新部署应用程序的情况下添加新的批处理文件,那么使用枚举是可以的...但是我认为最灵活的方法是在配置中定义密钥/文件名对的列表。

要添加新的批处理文件,您只需将其添加到配置文件/重新启动/告诉您的用户密钥。 您只需要处理未知密钥/文件未找到异常。

Using enums is ok if you don't need to add new batch files without recompiling / redeploying your application... however I think most flexible approach is to define a list of key / filename pairs in your config.

To add a new batch file you just add it to the config file / restart / tell your user the key. You just need to handle unknown key / file not found exceptions.

霊感 2024-07-29 20:48:46

ExecuteBatch 真的有必要仅对有限数量的可能文件名起作用吗?
你为什么不去做呢

public void ExecuteBatch(string batchFile)
{
    ExecuteBatchFile(batchFile);
}

Is it really necessary that ExecuteBatch works on limited number of possible file names only?
Why don't you just make it

public void ExecuteBatch(string batchFile)
{
    ExecuteBatchFile(batchFile);
}
缺⑴份安定 2024-07-29 20:48:46

后一种情况的问题是,如果某些内容传递了不在字典内的无效值。 switch 语句中的默认值提供了一种简单的方法。

但是......如果你的枚举将会有很多条目。 字典可能是更好的选择。

无论哪种方式,我都会推荐某种方法来保护输入值,即使在 ammoQ 的答案中也不会导致严重错误。

The problem with the latter case is if something passed an invalid value that is not inside the dictionary. The default inside the switch statement provides an easy way out.

But...if you're enum is going to have a lot of entries. Dictionary might be a better way to go.

Either way, I'd recommend some way to provide protection of the input value from causing a bad error even in ammoQ's answer.

时光沙漏 2024-07-29 20:48:46

第二种方法更好,因为它将批处理文件对象(枚举)与字符串链接起来。

但是说到设计,将枚举和字典分开并不是很好; 您可以将此视为替代方案:

public class BatchFile {
    private batchFileName;

    private BatchFile(String filename) {
        this.batchFileName = filename;
    }
    public const static BatchFile batch1 = new BatchFile("file1");
    public const static BatchFile batch2 = new BatchFile("file2");

    public String getFileName() { return batchFileName; }
}

您可以选择将构造函数保留为私有,或将其公开。

干杯,

jrh。

The second approach is better, because it links the batch file objects (enums) with the strings..

But talking about design, it would not be very good to keep the enum and the dictionary separate; you could consider this as an alternative:

public class BatchFile {
    private batchFileName;

    private BatchFile(String filename) {
        this.batchFileName = filename;
    }
    public const static BatchFile batch1 = new BatchFile("file1");
    public const static BatchFile batch2 = new BatchFile("file2");

    public String getFileName() { return batchFileName; }
}

You can choose to keep the constructor private, or make it public.

Cheers,

jrh.

傾城如夢未必闌珊 2024-07-29 20:48:46

第一个解决方案(交换机)简单明了,您实际上不必使其变得更复杂。

使用枚举的替代方法是使用返回具有相关数据集的类实例的属性。 这是相当可扩展的; 如果您稍后需要 Execute 方法对某些批次以不同的方式工作,您可以让属性返回具有不同实现的子类,并且仍然以相同的方式调用它。

public class BatchFile {

   private string _fileName;

   private BatchFile(string fileName) {
      _fileName = fileName;
   }

   public BatchFile Batch1 { get { return new BatchFile("Batch1.bat"); } }
   public BatchFile Batch2 { get { return new BatchFile("Batch2.bat"); } }

   public virtual void Execute() {
      ExecuteBatchFile(_fileName);
   }

}

用法:

BatchFile.Batch1.Execute();

The first solution (the switch) is simple and straight forward, and you really don't have to make it more complicated than that.

An alternative to using an enum could be to use properties that returns instances of a class with the relevant data set. This is quite expandable; if you later on need the Execute method to work differently for some batches, you can just let a property return a subclass with a different implementation and it's still called in the same way.

public class BatchFile {

   private string _fileName;

   private BatchFile(string fileName) {
      _fileName = fileName;
   }

   public BatchFile Batch1 { get { return new BatchFile("Batch1.bat"); } }
   public BatchFile Batch2 { get { return new BatchFile("Batch2.bat"); } }

   public virtual void Execute() {
      ExecuteBatchFile(_fileName);
   }

}

Usage:

BatchFile.Batch1.Execute();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文