【问题标题】:Create implicit cast for enum value为枚举值创建隐式转换
【发布时间】:2017-03-28 14:50:00
【问题描述】:

我用自己的枚举 MessageBoxButton 创建了自己的 MessageBox :

public enum MyMessageBoxButton
{
    OK = MessageBoxButton.OK,
    OKCancel = MessageBoxButton.OKCancel,
    YesNoCancel = MessageBoxButton.YesNoCancel,
    YesNo = MessageBoxButton.YesNo,
    NowLaterCancel = 5,
}

如您所见,它就像 System.Windows.MessageBoxButton 多了 1 个值。

对于我的 MyMessageBox 类,我有以下功能:

public static MessageBoxResult Show(String caption, String message, MyMessageBoxButton button, MessageBoxImage icon)
{
    ...
}

有没有办法用MessageBoxButton 调用Show 并将值隐式转换为MyMessageBoxButton

【问题讨论】:

  • 我可以建议对您的解决方案进行更改吗?您有一个列出可能的按钮组合的枚举。但是,您已经为多个变体创建了一个值。这是不灵活的。我建议如下:None = 0,OK = 1,Yes = 2,No = 4,Cancel = 8,Later = 16 这样您就可以使用按位运算来锻炼哪些按钮可用。 1 + 8 = 9(确定,取消)2 + 4 = 6(是,否)等
  • 你试过switch/case吗?你所谓的casting实际上是mapping,但是你必须为那个额外的价值做点什么,不是吗?
  • 我尝试了 itsme86 提供的解决方案,它可以工作。就像我不明白我应该使用try/catch
  • 这是 wpf 吗?因为在 winforms 中它将是 MessageBoxButtons 而不是 MessageBoxButton
  • @RossMiller - 这是与System.Windows.Forms.MessageBoxButtons 相同的枚举,只是他将最后一项从RetryCancel 重命名为NowLaterCancel 并删除了AbortRetryCancel。该设计有效,因为它允许用户在一个参数中将所需的按钮配置传递给消息框。

标签: c# wpf enums


【解决方案1】:

您可以创建一个将MessageBoxButtons 转换为MyMessageBoxButton 的转换器方法,创建一个采用MessageBoxButtonsShow 方法的重载,然后在该方法中您将进行转换并调用您的现有的Show 方法。

由于您没有匹配所有项目的枚举值(例如AbortRetryIgnore),因此您必须决定如果有人选择其中之一,则显示哪个按钮组合:

public static MyMessageBoxButton ConvertToMyMessageBoxButton(MessageBoxButtons input)
{
    MyMessageBoxButton result;

    switch (input)
    {
        case MessageBoxButtons.OK:
            result = MyMessageBoxButton.OK;
            break;
        case MessageBoxButtons.OKCancel:
            result = MyMessageBoxButton.OKCancel;
            break;
        case MessageBoxButtons.RetryCancel:
            result = MyMessageBoxButton.NowLaterCancel;
            break;
        case MessageBoxButtons.YesNo:
            result = MyMessageBoxButton.YesNo;
            break;
        case MessageBoxButtons.YesNoCancel:
            result = MyMessageBoxButton.YesNoCancel;
            break;
        default:
            // AbortRetryIgnore will fall through to this
            result = MyMessageBoxButton.OKCancel;
            break;
    }

    return result;
}

然后您将在 Show 方法的重载中使用 Convert 方法进行转换并调用您原来的 Show

public static MessageBoxResult Show(String caption, String message, 
    MessageBoxButtons button, MessageBoxImage icon)
{
    return Show(caption, message, ConvertToMyMessageBoxButton(button), icon);
}

【讨论】:

  • 实际上它适用于演员,但我会改变你的解决方案,更易于维护。
【解决方案2】:

您可以为 Show() 创建一个重载,它接受 MessageBoxButton 并强制转换它:

public static MessageBoxResult Show(String caption, String message, MessageBoxButton button, MessageBoxImage icon)
{
    return Show(caption, message, (MyMessageBoxButton)(int)button, icon);
}

不确定是否需要第一次转换为 int。不先尝试。

请注意,这取决于两个枚举的值是否匹配。例如,MessageBoxButton.YesNoCancel 必须像 MyMessageBoxButton 一样为 3。

【讨论】:

  • 需要演员表。由于 C# 不允许隐式转换
  • 这太容易出错了。我真的会提供一种方法,它为使用switch...case 的给定MessageBoxButton 返回MyMessageBoxButton
  • 我尝试了一种新的显示方法:return Show(caption, message, (MessageBoxSVButton)button, icon);,它似乎有效。我不明白我应该如何处理 switch/case
  • @TimSchmelter 我不明白这有什么好处很多。如果 .NET 更改了您的枚举值,那么您的映射仍将静默中断。您将不得不更改映射或枚举。选择你的毒药。我一点也不喜欢这个主意。我只是想给出一个解决方案。
  • 我修改了MyMessageBoxButton 的定义,以确保转换正确的值。
猜你喜欢
  • 1970-01-01
  • 2019-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
相关资源
最近更新 更多