打开一个真表达式c#

打开一个真表达式c#,c#,C#,我本想做些像这样的事情 switch(true) { case box1.Checked: do_something(); break; case box2.Checked: do_something_else(); and_some_more(); break; default: complain_loudly(); } 但这在c#中是不允许的;它是用php编写的 除了游泳池,还有更整洁的方法吗 if (box1

我本想做些像这样的事情

switch(true) {
    case box1.Checked:
       do_something(); break;
    case box2.Checked:
       do_something_else();
       and_some_more(); break;
    default:
       complain_loudly();
}
但这在c#中是不允许的;它是用php编写的

除了游泳池,还有更整洁的方法吗

if (box1.Checked) {
   do_something();
} else if (box2.checked)
  ...

我会尝试这样的方法-从集合中找到fist checked复选框,然后按checked控件的名称切换大小写。。。 大概是这样的:

var checkedCb = this.Controls.OfType<CheckBox>().Where(c => c.Checked).First();

switch (checkedCb.Name)
{
    case "cbOne":
        break;
    case "cbTwo":
        break;
    default:
        break;

}
CaseHelper.Switch(true, 
    (Branch<bool>)Tuple.Create<bool, Action>(box1.Checked, doSomething1),
    (Branch<bool>)Tuple.Create<bool, Action, Mode>(box2.Checked, () => doSomething2(), Mode.Break)
);
var checkedCb=this.Controls.OfType()。其中(c=>c.Checked.First();
开关(checkedCb.Name)
{
案例“cbOne”:
打破
案例“cbTwo”:
打破
违约:
打破
}

PHP解决切换问题的方式似乎与C#不同。

在C#中,切换表达式,并使用大小写定义所切换表达式的可能常量结果。关于C#开关,最巧妙的一点是它可能会被优化,这要求案例是常量表达式

  • 你的第一个问题是,你的案例不是一成不变的
  • 作为第1点的结果:如果两个复选框都被选中,那么应该执行哪一个?这是一个会导致运行时问题的问题,无法在编译时进行计算。C#将不允许具有相同值的多个案例
  • 我不想在这里提供任何优化的例子,因为我会说很多谎话。如果您想了解更多关于这些优化的信息,可以阅读Eric Lipper的博客文章:

    作为解决方案:亲吻
    Keepitsimplestupid-意思-如果需要,请使用


    编辑: 我不认为这会增加代码的可读性和简单性。这基本上只是我在尝试做一些奇怪的事情,比如PHP中的switch语句<请不要用它。我不建议使用它。 (与简单的
    if-else
    )相比,它在最初和每次调用过程中占用更多的空间和时间)

    公共部分类主窗口:窗口
    {
    专用复选框[]u复选框;
    私有字典_checkboxActions=新字典();
    公共主窗口()
    {
    初始化组件();
    列表复选框=新建列表();
    复选框。添加(复选框1);
    复选框。添加(复选框2);
    _checkboxes=checkboxes.ToArray();
    _添加(CheckBox1.GetHashCode(),OnCheckBox1Checked);
    _添加(CheckBox2.GetHashCode(),OnCheckBox2Checked);
    }
    public void invokeCECKBOxActions()
    {
    行动;
    foreach(在_复选框中的var复选框)
    {
    如果(checkbox.IsChecked==true)
    {
    int checkboxPtr=checkbox.GetHashCode();
    if(_checkboxActions.TryGetValue(checkboxPtr,out action))
    {
    动作();
    }
    }
    }
    }
    私有void OnCheckBox1Checked()
    {
    Console.WriteLine(“选中了复选框1”);
    }
    私有void OnCheckBox2Checked()
    {
    Console.WriteLine(“复选框2已选中”);
    }
    }
    
    我认为此代码将具有所需的行为

    public enum Mode { None, Break, Continue };
    
    public sealed class Branch<T>
    {
        public Mode Mode { get; }
        public T Value { get; }
        public Action Action { get; }
    
        public Branch(T value, Action action, Mode mode = Mode.None)
        {
            Value = value;
            Action = action;
            Mode = mode;
        }
    }
    
    public static class CaseHelper
    {
        public static void Switch<T>(T condition, params Branch<T>[] branches)
        {
            bool Continue = false;
            foreach (var branch in branches)
            {
                if (branch.Value.Equals(condition) || Continue)
                {
                    branch.Action();
                }
    
                if (branch.Mode == Mode.Break) break;
                Continue = branch.Mode == Mode.Continue;
            }
        }
    }
    
    公共枚举模式{None,Break,Continue};
    公共密封类分行
    {
    公共模式模式{get;}
    公共T值{get;}
    公共行动行动{get;}
    公共分支(T值,动作,模式=模式。无)
    {
    价值=价值;
    行动=行动;
    模式=模式;
    }
    }
    公共静态类CaseHelper
    {
    公共静态无效开关(T条件,参数分支[]分支)
    {
    bool Continue=false;
    foreach(分支中的var分支)
    {
    if(分支值等于(条件)| |继续)
    {
    分支。动作();
    }
    如果(branch.Mode==Mode.Break)中断;
    Continue=branch.Mode==Mode.Continue;
    }
    }
    }
    
    用法:

    CaseHelper.Switch(true, new Branch<bool>(box1.Checked, doSomething1), new Branch<bool>(box2.Checked, () => doSomething2()));
    
    caseheloper.Switch(true,新分支(box1.Checked,doSomething1),新分支(box2.Checked,()=>doSomething2());
    
    但是它看起来不太优雅

    附言: 我们可以向分支添加隐式转换运算符

    public static implicit operator Branch<T>(Tuple<T, Action, Mode> triple)
    {
        return new Branch<T>(triple.Item1, triple.Item2, triple.Item3);
    }
    
    public static implicit operator Branch<T>(Tuple<T, Action> duple)
    {
        return new Branch<T>(duple.Item1, duple.Item2);
    }
    
    公共静态隐式运算符分支(元组三元组)
    {
    返回新分支(triple.Item1、triple.Item2、triple.Item3);
    }
    公共静态隐式运算符分支(Tuple duple)
    {
    返回新分支(duple.Item1,duple.Item2);
    }
    
    然后用这样的方法:

    var checkedCb = this.Controls.OfType<CheckBox>().Where(c => c.Checked).First();
    
    switch (checkedCb.Name)
    {
        case "cbOne":
            break;
        case "cbTwo":
            break;
        default:
            break;
    
    }
    
    CaseHelper.Switch(true, 
        (Branch<bool>)Tuple.Create<bool, Action>(box1.Checked, doSomething1),
        (Branch<bool>)Tuple.Create<bool, Action, Mode>(box2.Checked, () => doSomething2(), Mode.Break)
    );
    
    caseheloper.Switch(true,
    (分支)Tuple.Create(box1.Checked,doSomething1),
    (分支)Tuple.Create(box2.Checked,()=>doSomething2(),Mode.Break)
    );
    
    与C#7一起使用
    案例
    一起使用时
    。另见

    输出:

    box2 is checked
    

    C#不支持这样的可变情况。简单的if/else if有什么问题?这可能是相同的代码行数。如果需要多个复选框,请使用checkboxlist,您肯定应该使用VB。它真的很棒,做了所有我们都试图将复选框状态与行为联系起来的事情。很高兴我们两人都认为它看起来不太优雅:)+1这是一个巧妙的把戏!作为一个同时使用C#和VB的人,我认为C#真的可以在这方面从VB那里学到一两个技巧(考虑到多年来模式匹配的不断改进,它似乎最终会达到目的)。