2016-03-09 4 views
16

Ho alcune pagine, ognuna con una proprietà denominata Data. In un'altra pagina che sto impostando questi dati in questo modo:Utilizzo dell'operatore null-condizionale sul lato sinistro di un'assegnazione

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

C'è la possibilità di utilizzare l'operatore null-subordinato MyPage? Sto pensando a qualcosa di simile:

MyPage?.Data = this.data; 

Ma quando scrivo in questo modo, ho il seguente errore:

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

Lo so che è perché MyPage potrebbe essere nullo e la mano sinistra il lato non sarebbe più una variabile.

Non è che non posso usarlo come ho già ma voglio solo sapere se c'è qualche possibilità di usare l'operatore condizionale nullo su questo.

+7

Dovreste essere in grado di creare un metodo 'SetData' e fare' MyPage1? .SetData (this.data); ' –

+1

Possibile duplicato di [Perché C# 6.0 non consente di impostare le proprietà di una struttura nullable non nulla quando si utilizza l'operatore di propagazione null?] (Http://stackoverflow.com/questions/31035022/why-c-sharp-6-0-doesnt-let-to -set-properties-of-a-non-null-nullable-struct-when) –

+0

Operatore di propagazione/condizionale null per accedere alle proprietà, non impostarle. Quindi non puoi usarlo. –

risposta

6

L'operatore di propagazione null restituisce un valore. E poiché devi avere una variabile sul lato sinistro di un compito, e non un valore, non puoi usarlo in questo modo.

Certo, è possibile rendere le cose più brevi utilizzando l'operatore di tenario, ma che, d'altra parte, non aiuta realmente l'aspetto di leggibilità.

Il commento di Joachim Isaksson sulla tua domanda mostra un approccio diverso che dovrebbe funzionare.

1

Prova questo Aggiungi tutte le tue pagine a myPageList.

IEnumerable<MyPage> myPageList; 

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

Come Joachim Isaksson suggerito nei commenti, ora ho un metodo SetData(Data data) e usarlo in questo modo:

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

Un metodo di estensione SetValue generico (ma solo per le proprietà ref) sarebbe:

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

e verrà utilizzato come

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

Hai provato questo? Non c'è assolutamente alcun modo per farlo funzionare ... 'La proprietà T 'dovrebbe essere un parametro di riferimento per il cambiamento, perché l'unica cosa che stai facendo è impostare la copia locale della proprietà all'interno della funzione, e non puoi hanno metodi di estensione "this ref'" e C# non consente l'accesso alle proprietà (diversamente da VB, che in realtà è un vero peccato). –

+0

Oh, hai ragione - funziona solo con parametri ref (quindi nel mio caso ha funzionato sempre ... per caso) – copa017

0

Sono venuto con la seguente estensione,

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

che può essere chiamata a livello globale; questo funziona solo su proprietà pubbliche.

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

Il seguente migliorata versione funziona su qualsiasi cosa,

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

E può anche essere chiamato a livello globale,

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

Ma il nome di estensione è un po 'fuorviante, in quanto il Action non richiede esclusivamente un incarico.