2016-03-09 18 views
16

我有几个页面,每个页面都有一个名为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; 

但是,当我把它写这样的,我得到以下错误:

The left-hand side of an assignment must be a variable, property or indexer.

我知道这是因为MyPage可能是零和左手方面不会再是变数。

这不是我不能像我已经使用它,但我只是想知道是否有任何可能使用这个空条件运算符。

+7

您应该能够创建一个'SetData'方法并执行'MyPage1?.SetData(this.data);' –

+1

可能的重复[Why C#6。0在使用Null传播运算符时不允许设置非空的可空结构的属性?](http://stackoverflow.com/questions/31035022/why-c-sharp-6-0-doesnt-let-to -set-properties-of-a-non-null-nullable-struct-when) –

+0

空传播/条件运算符用于访问属性,不设置它们。因此你不能使用它。 –

回答

6

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

当然,你可以通过使用tenary操作符缩短事情的时间,但另一方面,这并不能真正帮助可读性方面。

Joachim Isaksson对你的问题的评论显示了一种不同的方法。

1

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

IEnumerable<MyPage> myPageList; 

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

正如约阿希姆伊萨克森的意见建议,我现在有一个方法SetData(Data data),并使用它像这样:

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

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

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

而且会像

ButtonOrNull?.Visibility.SetValue(Visibility.Hidden); 
使用
+1

你测试过了吗?这绝对没有办法,这将工作...''T属性'必须是一个ref参数的变化,因为你唯一要做的就是在该函数内设置属性的本地副本,并且你不能有'这个ref'扩展方法也不允许C#允许ref访问属性(不像VB,这实际上是一个真正的耻辱)。 –

+0

哦,你是对的 - 它只适用于参数参数(所以在我的情况下它总是工作......不小心) – copa017

0

我想出了下面的扩展,

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没有专门要求一项任务。