简体   繁体   English

C#长开关语句

[英]C# Long Switch Statements

I've seen the articles on StackOverflow regarding c++ long switch statements, but c# is different in this regard. 我看过StackOverflow上有关c ++ long switch语句的文章,但是c#在这方面有所不同。

Specifically, I would like to replace a hugely-long switch statement in c# code, where each case statement does the same thing, just the field name changes. 具体来说,我想用c#代码替换一个很长的switch语句,其中每个case语句执行相同的操作,只是字段名称发生变化。

The code looks like this: 代码如下:

 case Fields.TRANSMITTERCONTACTPHONEEXT:
                {
                    int lengthNeeded = 0;
                    int currentLength = TransmitterContactTelephoneExtension.Length;
                    int lengthRequired = TransmitterContactTelephoneExtensionLength;
                    if (currentLength < lengthRequired)
                    {
                        lengthNeeded = lengthRequired - currentLength;
                        for (int i = 0; i < lengthNeeded; i++)
                        {
                            TransmitterContactTelephoneExtension += " ";
                        }
                    }
                } break;
            case Fields.TRANSMITTERFEIN:
                {
                    int lengthNeeded = 0;
                    int currentLength = TransmitterFEIN.Length;
                    int lengthRequired = TransmitterFEINLength;
                    if (currentLength < lengthRequired)
                    {
                        lengthNeeded = lengthRequired - currentLength;
                        for (int i = 0; i < lengthNeeded; i++)
                        {
                            TransmitterFEIN += " ";
                        }
                    }
                } break;

I'd like to just get this down to a single function that can figure out which field I mean without having to use a switch statement. 我只想将其归结为一个函数,无需使用switch语句就可以弄清楚我的意思是哪个字段。 Is there a way to pass in a variable containing the field name? 有没有办法传入包含字段名称的变量?

This just looks like the code for a string pad function repeated multiple times. 看起来就像一个字符串填充函数的代码重复了多次。 You could just have 你可能只有

case Fields.TRANSMITTERCONTACTPHONEEXT:
     TransmitterContactTelephoneExtension = TransmitterContactTelephoneExtension.PadRight(TransmitterContactTelephoneExtensionLength, ' ');
     break;
    ...

Any time that you find yourself repeating code over and over, you probably can break it out into a separate function (if one does not already exist) and just call it with the right parameters. 每当您发现自己一遍又一遍地重复代码时,就可以将其分解为一个单独的函数(如果尚不存在),并使用正确的参数进行调用。

And this also makes me wonder if you need the switch case statement at all, and not just a series of pad statements. 这也让我想知道您是否根本需要switch case语句,而不仅仅是一系列pad语句。 But that is going further out (in scope) in your code. 但这在您的代码中(在范围上)更进一步。 And your post does not give us enough info to go there. 而且您的帖子没有给我们足够的信息。

Finally, somewhat applicable to your question, my rule of thumb (not originally mine, but I forget where I got it) is that if a method is more than a pageful (intentionally vague term), then I need to break it up into other separate methods. 最后,在某种程度上适用于您的问题,我的经验法则(最初不是我的,但我忘了我从哪里得到的)是,如果某个方法不仅仅是一个分页的(故意模糊的术语),那么我需要将其分解为其他方法单独的方法。 That allows me to look at a method and understand it without scrolling around. 这使我无需滚动即可查看并理解方法。 It also forces me to separate a longer process into smaller logical steps. 这也迫使我将较长的过程分成较小的逻辑步骤。

Place all the changeable values into arrays and index into it. 将所有可变值放入数组中并对其进行索引。 Make sure the enum int values are the same as the data in the target arrays. 确保枚举int值与目标数组中的数据相同。

var current = (int) Fields.TRANSMITTERCONTACTPHONEEXT;

int lengthNeeded = 0;
int currentLength = LengthData[ current ] ;
int lengthRequired = RequiredData[current ];

if (currentLength < lengthRequired)
{
      lengthNeeded = lengthRequired - currentLength;
      for (int i = 0; i < lengthNeeded; i++)
      {
         Extensions[ current ] = Extensions[ current ] + " ";
      }
}

This post looks at the pattern of the operations in the switch and does not address any localized deficiencies of individual operations. 这篇文章探讨了交换机中的操作模式 ,并没有解决单个操作的任何局部缺陷。 Please look at each of the individual operations and where needed improve it for optimal operational efficiencies. 请查看每个单独的操作,并在需要的地方对其进行改进以实现最佳的操作效率。

Declare the variables in advance, and use the switch only for the assignments that differ: 预先声明变量,并仅将switch用于不同的分配:

int currentLength;
int lengthRequired;

switch (whatever) {
case Fields.TRANSMITTERCONTACTPHONEEXT:
    currentLength = TransmitterContactTelephoneExtension.Length;
    lengthRequired = TransmitterContactTelephoneExtensionLength;
    break;
case Fields.TRANSMITTERFEIN:
    currentLength = TransmitterFEIN.Length;
    lengthRequired = TransmitterFEINLength;
    break;
default:
    throw new Exception(); // Without this, the compiler will complain about uninitialized variables
}

int lengthNeeded = 0;
if (currentLength < lengthRequired)
{
    lengthNeeded = lengthRequired - currentLength;
    for (int i = 0; i < lengthNeeded; i++)
    {
        TransmitterFEIN += " ";
    }
}

switch (whatever) {
case Fields.TRANSMITTERCONTACTPHONEEXT:
    TransmitterContactTelephoneExtension += " ";
    break;
case Fields.TRANSMITTERFEIN:
    TransmitterFEIN += " ";
    break;
}

Edit: OmegaMan's solution is way better if you have the option of replacing the variables with an array. 编辑:如果您可以选择用数组替换变量,则OmegaMan的解决方案会更好。

You really should break this out into a method. 您确实应该将此分解为一种方法。 So that you are not duplicating code over and over. 这样您就不会一遍又一遍地复制代码。 That is inefficient and can lead to potential errors when updating. 这样效率低下,并且可能在更新时导致潜在的错误。

Also instead of looping you should make use of the PadRight() method on strings. 同样,除了循环之外,还应该在字符串上使用PadRight()方法。

I would do this: 我会这样做:

case Fields.TRANSMITTERCONTACTPHONEEXT:
     TransmitterContactTelephoneExtension = PadString(TransmitterContactTelephoneExtensionLength, TransmitterContactTelephoneExtension);
     break;
case Fields.TRANSMITTERFEIN:
     TransmitterFEIN = PadString(TransmitterFEINLength, TransmitterFEIN);
     break;


private string PadString(int requiredLen, string value)
{
     if (value == null) return String.Empty.PadRight(requiredLen, ' '); //Create an empty string when the value is null
     return value.PadRight(requiredLen, ' ');
}

To me it seems like the code we can't see needs some refactoring, but based on what we can see, I would recommend doing the following: 在我看来,似乎看不到的代码需要一些重构,但是根据我们看到的内容,我建议执行以下操作:

// 1. Have a class to hold your data
class FieldData
{
    public string Value { get; set; }
    public int LengthRequired { get; set; }

    public string RightPaddedValue
    {
        get { return Value.PadRight(LengthRequired, ' '); }
    }
}

// 2. Fill your data into a dictionary somehow... for example:
Dictionary<Fields, FieldData> fields = new Dictionary<Fields, FieldData>
{
    { 
        Fields.TRANSMITTERCONTACTPHONEEXT, 
        new FieldData {
            Value = TransmitterContactTelephoneExtension,
            LengthRequired = TransmitterContactTelephoneExtensionLength
        }
    },
    { 
        Fields.TRANSMITTERFEIN,
        new FieldData {
            Value = TransmitterFEIN,
            LengthRequired = TransmitterFEINLength
        }
    }
};

// 3. Then use the data from that dictionary in your code:
FieldData data = fields[selectedField];
data.RightPaddedValue; // use RightPaddedValue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM