如何作为参数传递时如何触发枚举属性的setter?

时间:2016-11-13 09:52:12

标签: c# enums reference c#-6.0

想象一下,你有一个属性和一个私有字段:

private MessageBoxResult doNotUseMe_Result;

public MessageBoxResult MyResult
{
    get { return doNotUseMe_Result; }
    set
    {
        doNotUseMe_Result = value;
    }
}

MessageBoxResult是一个枚举,用于获取MessageBox(WPF)的结果。然而,在将MyResult传递给方法时遇到问题,因为它会自动使用枚举的值类型,并且GC会收集更改的结果,因为它现在是一个全新的变量在我的方法范围内(TaskBasedShow)......

我目前的设置:

public delegate void OnResult(MessageBoxResult res);

private MessageBoxResult doNotUseMe_Result;

public MainWindow()
{
    InitializeComponent();

    OnRes += MessageBox_OnRes;

    TaskBasedShow("My message", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Question, MyResult);
}

public MessageBoxResult MyResult
{
    get { return doNotUseMe_Result; }
    set
    {
        doNotUseMe_Result = value;
        OnRes?.Invoke(value);
    }
}


public void TaskBasedShow(string message, string caption, MessageBoxButton buttons,
        MessageBoxImage image, MessageBoxResult resultprop)
{
    Task.Factory.StartNew(() => { resultprop = MessageBox.Show(message, caption, buttons, image); });
}

/// <summary>
///     Is getting triggered after the user pressed a button.
/// </summary>
/// <param name="res">The pressed button.</param>
private void MessageBox_OnRes(MessageBoxResult res)
{
    MessageBox.Show(res.ToString());
}


public event OnResult OnRes;

我确实已阅读以下文件:

但似乎enum没有提供Set(value)方法。

问题:

设置枚举属性的变量(在mothod 中)时,setter不会被触发,因此也不会触发我的自定义事件。

应该做什么:

设置属性时应该触发OnRes因为我的setter被触发,因此我的订阅者是OnResult事件。工作范例:

public MainWindow()
{
    InitializeComponent();

    OnRes += MessageBox_OnRes;

    MyResult = MessageBoxResult.Cancel;
}

它将打开另一个显示“取消”的消息框

注意:

一种解决方案是使用TaskBasedShow内的属性:

Task.Factory.StartNew(() => { MyResult = MessageBox.Show(message, caption, buttons, image); });

因为它现在使用引用类型而不是传递的值类型。

1 个答案:

答案 0 :(得分:3)

您应该使用回调来获取结果值

public async void TaskBasedShow( 
    string message, 
    string caption, 
    MessageBoxButton buttons,
    MessageBoxImage image, 
    Action<MessageBoxResult> resultCallback)
{
    var result = await Task.Run(() => MessageBox.Show(message, caption, buttons, image ) );
    resultCallback( result );
}

并将其称为

TaskBasedShow(
    "My message", 
    "My caption", 
    MessageBoxButton.YesNo, 
    MessageBoxImage.Question, 
    r => MyResult = r );