小编典典

有没有比这更好的选择来“打开类型”?

all

看到 C#
不能switch在类型上使用(我认为没有将其添加为特例,因为is关系意味着可能应用多个不同case的类型),除此之外还有更好的方法来模拟打开类型吗?

void Foo(object o)
{
    if (o is A)
    {
        ((A)o).Hop();
    }
    else if (o is B)
    {
        ((B)o).Skip();
    }
    else
    {
        throw new ArgumentException("Unexpected type: " + o.GetType());
    }
}

阅读 82

收藏
2022-03-28

共1个答案

小编典典

C# 中肯定缺少切换类型。为了在没有大型 if/else if/else语句的情况下执行此操作,您需要使用不同的结构。不久前我写了一篇博文,详细介绍了如何构建 TypeSwitch 结构。

https://docs.microsoft.com/archive/blogs/jaredpar/switching-on-
types

短版:TypeSwitch 旨在防止冗余转换并提供类似于普通 switch/case 语句的语法。例如,这是 TypeSwitch 在标准 Windows
窗体事件中的作用

TypeSwitch.Do(
    sender,
    TypeSwitch.Case<Button>(() => textBox1.Text = "Hit a Button"),
    TypeSwitch.Case<CheckBox>(x => textBox1.Text = "Checkbox is " + x.Checked),
    TypeSwitch.Default(() => textBox1.Text = "Not sure what is hovered over"));

TypeSwitch 的代码实际上非常小,可以很容易地放入您的项目中。

static class TypeSwitch {
    public class CaseInfo {
        public bool IsDefault { get; set; }
        public Type Target { get; set; }
        public Action<object> Action { get; set; }
    }

    public static void Do(object source, params CaseInfo[] cases) {
        var type = source.GetType();
        foreach (var entry in cases) {
            if (entry.IsDefault || entry.Target.IsAssignableFrom(type)) {
                entry.Action(source);
                break;
            }
        }
    }

    public static CaseInfo Case<T>(Action action) {
        return new CaseInfo() {
            Action = x => action(),
            Target = typeof(T)
        };
    }

    public static CaseInfo Case<T>(Action<T> action) {
        return new CaseInfo() {
            Action = (x) => action((T)x),
            Target = typeof(T)
        };
    }

    public static CaseInfo Default(Action action) {
        return new CaseInfo() {
            Action = x => action(),
            IsDefault = true
        };
    }
}
2022-03-28