39

我有几页,每页都有一个名为Data. 在另一个页面上,我将这些数据设置为:

if (MyPage1 != null)
    MyPage1.Data = this.data;
if (MyPage2 != null)
    MyPage2.Data = this.data;
if (MyPage3 != null)
    MyPage3.Data = this.data;

是否有可能在 上使用空条件运算符MyPage?我在想这样的事情:

MyPage?.Data = this.data;

但是当我这样写时,我收到以下错误:

赋值的左侧必须是变量、属性或索引器。

我知道这是因为MyPage可能为 null 并且左侧不再是变量。

并不是我不能像我已经拥有它那样使用它,而是我只想知道是否有可能在此使用空条件运算符。

4

7 回答 7

18

空传播运算符返回一个值。而且由于您必须在赋值的左侧有一个变量,而不是一个值,所以您不能以这种方式使用它。

当然,您可以使用三元运算符使事情变得更短,但另一方面,这并不能真正帮助提高可读性。

Joachim Isaksson 对您的问题的评论显示了一种应该有效的不同方法。

于 2016-03-09T09:11:49.417 回答
14

正如 Joachim Isaksson 在评论中建议的那样,我现在有一个方法SetData(Data data)并像这样使用它:

MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);
于 2016-03-09T09:46:16.907 回答
4

我想出了以下扩展,

public static class ObjectExtensions
{
    public static void SetValue<TValue>(this object @object, string propertyName, TValue value)
    {
        var property = @object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
        if (property?.CanWrite == true)
            property.SetValue(@object, value, null);
    }
}

可以全局调用;这仅适用于公共财产。

myObject?.SetValue("MyProperty", new SomeObject());

以下改进版本适用于任何东西,

public static void SetValue<TObject>(this TObject @object, Action<TObject> assignment)
{
    assignment(@object);
}

并且也可以全局调用,

myObject?.SetValue(i => i.MyProperty = new SomeObject());

但是扩展名有点误导,因为Action它并不完全需要赋值。

于 2018-01-23T19:51:11.283 回答
4

聚会晚了,但我带着类似的问题来到这篇文章。我采用了 SetValue 方法的想法,并创建了一个通用的扩展方法,如下所示:

/// <summary>
/// Similar to save navigation operator, but for assignment. Useful for += and -= event handlers. 
/// If <paramref name="obj"/> is null, then <paramref name="action"/> is not performed and false is returned.
/// If <paramref name="obj"/> is not null, then <paramref name="action"/> is performed and true is returned.
/// </summary>
public static bool SafeAssign<T>(this T obj , Action<T> action ) where T : class 
{
  if (obj is null) return false;
  action.Invoke(obj);
  return true;
}

示例用法,用于附加和分离事件处理程序:

public void Attach() => _control.SafeAssign(c => c.MouseDown += Drag);

public void Detach() => _control.SafeAssign(c => c.MouseDown-= Drag);

希望有人觉得它有用:)

于 2018-10-05T00:52:03.173 回答
1

试试这个将所有页面添加到 myPageList。

IEnumerable<MyPage> myPageList;

foreach(MyPage myPage in myPageList)
{
if (myPage != null)
    myPage.Data = this.data;
}
于 2016-03-09T09:15:33.107 回答
0

您可以使用扩展方法

 public static void NCC<T>(this T instance, System.Action<T> func)
        where T : class
{
        if (instance != null)
        {
            func(instance);
        }
}

MyPage1.NCC(_=>_.Data = this.data);
于 2020-09-29T08:19:28.977 回答
-1

一个通用的 SetValue 扩展方法(但仅适用于 ref 属性)将是:

    public static void SetValue<T>(this T property, T value)
    {
        property = value;
    }

并且会像这样使用

ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);
于 2017-05-29T11:18:55.210 回答