在赋值的左侧使用空条件运算符

时间:2016-03-09 09:03:59

标签: c# null-conditional-operator

我有几个页面,每个页面都有一个名为tf.textProperty().addListener((observable, oldValue, newValue) -> { if (isInvalid(newValue)) { tf.setText(oldValue); } }); 的属性。在另一个页面上,我正在设置这样的数据:

public static final String QUERY_STRING = "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/etc/workflow/instances]) and CONTAINS('status', 'COMPLETED') and contains('modelId', '/etc/workflow/models/dam/update_asset/jcr:content/model') and [data/payload/path]='%s' and endTime > CAST('%s' AS DATE)";
private void waitForDamUpdateImage(Session session, String path) throws WorkflowException, InterruptedException
{
    final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.GERMAN);
    final Date now = new Date();
    final Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date(now.getTime() - 2 * 60 * 1000));

    String queryString = String.format(QUERY_STRING, path, formatter.format(calendar.getTime()));

    Iterator iterator;

    do
    {
        //wait(100); this wait will produce IllegalMonitor... Exception
        iterator = QueryUtils.query(session, queryString);
    }
    while (!iterator.hasNext());
}

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

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

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

  

作业的左侧必须是变量,属性或索引器。

我知道这是因为MyPage可能为空,而左侧不再是变量。

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

7 个答案:

答案 0 :(得分:10)

空传播运算符返回一个值。因为你必须在作业的左侧有一个变量,而不是一个值,所以你不能以这种方式使用它。

当然,你可以通过使用tenary运算符来缩短时间,但另一方面,这对于可读性方面并没有什么帮助。

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

答案 1 :(得分:7)

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

MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);

答案 2 :(得分:2)

我提出了以下扩展,

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并不完全需要转让。

答案 3 :(得分:1)

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

IEnumerable<MyPage> myPageList;

foreach(MyPage myPage in myPageList)
{
if (myPage != null)
    myPage.Data = this.data;
}

答案 4 :(得分:1)

参加聚会的时间不算太晚,但是我以类似的问题来到本文。我想到了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);

希望有人发现它有用:)

答案 5 :(得分:0)

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

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

将像

一样使用
ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);

答案 6 :(得分: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);