【问题标题】:C# comparing multiple typeC#比较多种类型
【发布时间】:2019-09-28 13:50:20
【问题描述】:

我有以下遗留代码:

if (isOnMainWindow
    || (win.GetType() != typeof(winInputBox)
    && win.GetType() != typeof(winMessage)
    && win.GetType() != typeof(winMsgBox)
    && win.GetType() != typeof(winAbout))
    ApplicationCommands.Close.Execute(null, win);

这看起来很可怕。有没有办法像我一样比较多种类型的对象?

【问题讨论】:

    标签: c# typeof


    【解决方案1】:

    您可以使用 List 或 HashSet 来简化它

    var typesToIgnore = new List<Type> { 
        typeof(winInputBox), 
        typeof(winMessage), 
        typeof(winMsgBox), 
        typeof(winAbout) 
    };
    
    if (isOnMainWindow || !typesToIgnore.Contains(win.GetType()))
    {
    }
    

    【讨论】:

    • 差不多就是上面的答案
    • @kenny,OP 要求重构他的代码,所有答案都应该是上面的答案。这样做的主要好处是您在每个函数调用中都复制了类型,它们都包含在一个位置中。
    【解决方案2】:

    或者,如果您可以修改类,请创建一个虚拟接口,例如:

    public interface IShouldNotClose
    {
    }
    

    将界面定义为每个窗口的一部分,然后您的检查就变成了

    if (isOnMainWindow
        || !(win is IShouldNotClose))
        ApplicationCommands.Close.Execute(null, win);
    

    【讨论】:

    • 这个答案在他们开始编写时会很好,但是,但是修改遗留代码以添加接口,会导致更大的测试增量,并且会破坏打开和关闭原则的方式超过只是一个标准的重构
    • 但是这些窗口类型的代码没有变化。实际上,您所做的只是装饰类声明。
    • 你正在根据实现细节装饰你的班级。如果你需要在另一个类中复用这段代码,你需要再次装饰这个类
    • 重用发生在类之外,只需要标记公共代码即可识别。因此,您可以在任何 Window 类中重复使用它,只需将“IShouldNotClose”附加到类标题行,如下所示: public partial class MainWindow : Window, IShouldNotClose 这将不需要您在每个表单中多次执行此操作。
    • 这可能会迫使您多次执行此操作,因为操作人员声明这是遗留代码,并且不了解其架构。
    【解决方案3】:

    没有什么可以做你想做的,但为什么不使用更简单的语法:

    if (!(win is winInputBox) && !(win is winMessage) && !(win is winMsgBox) && !(win is winAbout)) ApplicationCommands.Close.Execute(null, win);
    

    或者,您可以使用一种方法让您的生活更轻松:

    public static IsNotOneOf(object obj, params Type[] types)
    {
        foreach (var type in types)
        {
            if (type.IsAssignableFrom(obj.GetType()) return false;
        }
    
        return true;
    }
    

    你可以这样使用它:

    if (IsNotOneOf(win, typeof(winInputBox), typeof(winMessage), typeof(winMsgBox), typeof(winAbout)) ApplicationCommands.Close.Execute(null, win);
    

    【讨论】:

    • 注意win is winInputBoxwin.GetType() == typeof(winInputBox)不完全一样,第一个会包含后代类型,第二个不会。
    • 是的,没错,但我认为这是 Otto 的意思。
    猜你喜欢
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多