替代使用if -else语句

Ven*_*kat 2 c# design-patterns

if --else if --block包含许多if语句的最佳替代方法是什么.

码:

 string word="";

 if(letter=='a')
    {
       // do some action
       call(a);
    } 
 else if (letter=='b')
   {

           call(b)
   }

 else if (letter=='c')
   {
       call(c)
   }
 else if (letter=='d')
   {
       // do some action
       call(d)
   }
 else if (letter=='e')
   {
       // do some action
       call(e)
   }

    ................

     ..............

 else if (letter=='z')
   {
       // do some action
        call(z)
   }
Run Code Online (Sandbox Code Playgroud)

如果有很多if-else语句,那么找到这种场景的解决方案的最佳方法是什么.有没有办法使用类/对象有效地设计这样的场景?

我相信我们中的许多人在设计/编码过程中都会面临这样的问题.有没有一种有效的方法来处理这种情况?

没有开关声明请.使用C#对象的有效设计算法将是最好的选择.

Jef*_*tin 6

在C#中,最直接的翻译是switch声明.虽然switch严格来说不是面向对象的构造,但char它也不是C#中的适当对象.

switch(letter)
{
    case 'a':
        call(a);
        break;

    case 'b':
        call(b);
        break;

    // and so on
}
Run Code Online (Sandbox Code Playgroud)

如果参数不是简单值类型而是对象,则使用虚方法而不是显式控制结构.这是真正的"面向对象"方式:在Smalltalk中ifTrue:,ifFalse:并且ifTrue:ifFalse:是Boolean将代码块作为参数的方法!不过,C#让这个相当冗长.

static class Example {
    static void Sample(ISpeaker input) {
        input.Speak(); // this call acts like a control structure
    }
}

interface ISpeaker {
    void Speak();
}

class Cat : ISpeaker {
    public void Speak() {
        Console.WriteLine("Meow");
    }
}

class Dog : ISpeaker {
    public void Speak() {
        Console.WriteLine("Woof");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您坚持使用简单类型,则另一种方法是显式调度表.

static readonly Dictionary<char, Action> dispatch
    = new Dictionary<char, Action> {
        { 'a', () => call(a) },
        { 'b', () => call(b) },
    };

static void Process(char letter) {
    dispatch[letter]();
}
Run Code Online (Sandbox Code Playgroud)

如果您的条件对于Dictionary基于调度的表而言过于复杂,则可以使用List基于线性的调度表,该表更接近于else-if链的行为:

static List<KeyValuePair<Func<char, bool>, Action>> dispatch
    = new List<KeyValuePair<Func<char, bool>, Action>>() {
        { x => x == 'a', () => call(a) },
        { x => x == 'b', () => call(b) },
        { x => true, () => callDefault() },
    };

static void Process(char letter) {
    dispatch.First(kvp => kvp.Key(letter)).Value();
}
Run Code Online (Sandbox Code Playgroud)