2016-03-09 16 views
16

Mam kilka stron, każda z właściwością o nazwie Data. Na innej stronie mam ustawienia te dane tak:Korzystanie z operatora warunkowego zerowego po lewej stronie przypisania

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

Czy istnieje możliwość, aby użyć operatora null uwarunkowane MyPage? Mam na myśli coś takiego:

MyPage?.Data = this.data; 

Ale kiedy piszę to w ten sposób, pojawia się następujący błąd:

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

wiem, że to dlatego, MyPage może być zerowa, a po lewej stronie strona nie będzie już zmienną.

Nie chodzi o to, że nie mogę go używać tak, jak już mam, ale chcę tylko wiedzieć, czy jest jakakolwiek możliwość skorzystania z tego warunkowego operatora.

+7

Powinieneś być w stanie stworzyć metodę 'SetData' i zrobić' MyPage1? .SetData (this.data); ' –

+1

Możliwy duplikat [Why C# 6.0 nie pozwala ustawić właściwości nie zerowej zerowej struktury przy użyciu operatora propagacji zerowej?] (Http://stackoverflow.com/questions/31035022/why-c-sharp-6-0-doesnt-let-to -set-właściwości-o-nie-null-null-struct-when) –

+0

Operator propagacji zerowej/warunkowej służy do uzyskiwania dostępu do właściwości, a nie ich ustawiania. Dlatego nie możesz z niego korzystać. –

Odpowiedz

6

Operator propagacji zerowej zwraca wartość. A ponieważ musisz mieć zmienną po lewej stronie zadania, a nie wartość, nie możesz jej używać w ten sposób.

Oczywiście, można skrócić czas za pomocą operatora napięciowego, ale z drugiej strony nie pomaga to w aspekcie czytelności.

Komentarze Joachima Isakssona na temat twojego pytania pokazują inne podejście, które powinno zadziałać.

1

Wypróbuj to Dodaj wszystkie swoje strony do myPageList.

IEnumerable<MyPage> myPageList; 

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

Jak Joachim Isaksson sugerowane w komentarzach, teraz mam metodę SetData(Data data) i używać go tak:

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

rodzajowe metodę rozszerzenia SetValue (ale tylko dla właściwości REF) będzie:

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

i będą wykorzystywane jak

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

Czy to testujesz? Nie ma absolutnie żadnego sposobu, żeby to zadziałało ... 'Właściwość T 'musi być parametrem ref, aby zmiana pozostała, ponieważ jedyną rzeczą, którą robisz, jest ustawienie lokalnej kopii właściwości wewnątrz funkcji, i nie możesz posiadają 'ten ref' 'metody rozszerzenia, ani C# nie pozwala na dostęp do właściwości (w przeciwieństwie do VB, co jest prawdziwym wstydem). –

+0

Och, masz rację - działa tylko z parametrami ref (więc w moim przypadku działało zawsze ... przez przypadek) – copa017

0

wymyśliłem następujący rozszerzeniu

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); 
    } 
} 

które mogą być nazywane globalnie; działa to tylko na nieruchomościach publicznych.

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

Poniżej poprawiona wersja działa na wszystko,

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

I mogą być również nazywane globalnie

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

Ale nazwa rozszerzenie jest nieco mylące, ponieważ Action nie wymaga wyłącznie zadanie.