2016-03-09 21 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沒有專門要求一項任務。