2009-06-25 19 views
22

Chcę zachować właściwość między ogłaszaniem zwrotnym w aplikacji ASP.Net. Obecnie to robi:Uzyskaj nazwę właściwości wewnątrz setera

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + "MyIndex"]; 
    } 
} 

ale woleliby coś takiego:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + #code_that_returns_property_name#]; 
    } 
} 

setera pominięte, ale to po prostu popycha wartości do sesji przy użyciu tego samego łańcucha. Czy istnieje sposób na wykorzystanie refleksji lub inne lepsze rozwiązanie?

+0

Wygląda na to, że wreszcie mamy jakieś [składniowej cukierków przyjście] (http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6. aspx), aby rozwiązać ten problem dla nas: "Często musisz podać ciąg, który nazywa jakiś element programu: podczas rzucania ArgumentNullException chcesz nazwać argument winny, podczas podnoszenia zdarzenia PropertyChanged chcesz nazwać zmienioną właściwość, itp. . " 'jeśli (x == null) wyrzuć nowy ArgumentNullException (nameof (x));' – JMD

Odpowiedz

24
public static int Dummy { 
    get { 
     var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4); 
     Console.WriteLine(propertyName); 
     return 0; 
    } 
} 
+1

Metoda GetCurrentMethod() zwróciła mi wyjątek System.ArgumentException ... –

+0

Nie, zadziałało. Nie wiem, skąd wziął się ten wyjątek. Działa teraz dobrze. Dokładnie to, czego potrzebowałem. –

+4

Z miłości do Boga, nie! Rezultat jest pięć razy dłuższy i 100 razy bardziej niejasny niż to, co zostało zastąpione! Dopóki nie będziesz ciągle zmieniał zdania na temat tego, jak nazwać to nieruchomością, jest to absurdalny pomysł. (... IMHO) –

13

Nie, nie ma prostego sposobu robienia tego, co chcesz zrobić. Myślę, że jesteś o wiele lepiej lepiej z kodem, który już napisałeś.

Edytuj:Ta odpowiedź otrzymała sporo głosów na dół i rozumiem dlaczego. Chociaż możliwe jest robienie tego, co OP chce zrobić, być może wszyscy powinniśmy przestać i zastanowić się, czy jest to możliwe, czy nie jest to konieczne. Parafrazując nieśmiertelne słowa: Dr. Ian Malcom, tylko dlatego, że możesz coś zrobić, nie znaczy, że powinieneś.

+0

Dlaczego głosowanie w dół? to najrozsądniejsza odpowiedź ... :) +1 ode mnie. –

+1

+1 ode mnie, to pomysł INSANÓW. Jeśli okaże się, że musisz dużo to robić, a nazwa ciągle się zmienia, więc zarządzanie nim staje się ciężarem, a następnie użyj pliku .tt do kodowania deklaracji właściwości lub czegoś podobnego. –

+0

+1 dla tej i zaakceptowanej odpowiedzi. Rozumiem, dlaczego OP chciałby to zrobić, oraz czynnik łagodzący: jeśli dana właściwość jest tylko jedną z 40, jest coś do powiedzenia dla pojedynczej implementacji, która jest oddzielona od 40 zakodowanych nazw właściwości. Czynnikiem łagodzącym jest oczywiście, jeśli OP wie, że te właściwości są ustawione tylko raz lub kilka razy, wydajność na tym poziomie jest dyskusyjna. Uniknij przedwczesnej optymalizacji. – JMD

7

Można użyć MethodInfo.GetCurrentMethod() Nazwa wrócić nazwę bieżącej metody.

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name]; 
    } 
} 

Ponieważ właściwości są implementowane jako metody pod maską, że powróci do nazwy takie jak "get_MyIndex". Jeśli nie chcesz, aby „get_” część można podciąg się kilka znaków:

public int MyIndex 
{ 
    get 
    { 
     return (int)Session[ToString() + MethodInfo.GetCurrentMethod().Name.Substring(4)]; 
    } 
} 
1

Powinieneś raczej użyć właściwości ViewState z kontrolą:

public int MyIndex { 
    get { 
     object index = ViewState["MyIndex"]; 
     return (null == index) ? -1 : (int)index; 
    } 
    set { 
     ViewState["MyIndex"] = value; 
    } 
} 
2

Można użyć wyrażenia drzewo, aby uzyskać nazwę członka. To trochę staw skokowy, ale działa. Oto kod.

private string GetPropertyName<TValue>(Expression<Func<BindingSourceType, TValue>> propertySelector) 
{ 
    var memberExpression = propertySelector.Body as MemberExpression; 
    if (memberExpression != null) 
    { 
     return memberExpression.Member.Name; 
    } 
    else 
    { 
     return string.empty;  
    } 
} 

Z tym kodem można wykonać następujące czynności

return (int)Session[ToString() + GetPropertyName(MyIndex)]; 

Kod bezwzględnie skradzione z odpowiedzią Romain w sprawie wątku

+0

Co za eleganckie rozwiązanie! +1 –

+0

Nie można rozwiązać symbolu "BindingSourceType" To jest projekt ASP.Net 3.5 ... –

+0

Jeśli czytasz oryginalną odpowiedź z innego wątku, oznacza to, że BindingSourceType jest nazwą klasy, która zawiera tę właściwość. Musisz użyć nazwy klasy, do której należy właściwość MyIndex. – adrianbanks

9

Korzystanie CallerMemberName jest o wiele szybszy i można go łatwo kopiować i wklejać w celu uzyskania dodatkowych właściwości.

private static object GetSessionValue([CallerMemberName]string propertyName = "") 
{ 
    return Session[propertyName]; 
} 

private static void SetSessionValue(object value, [CallerMemberName]string propertyName = "") 
{ 
    Session[propertyName] = value; 
} 

public int MyIndex 
{ 
    get { return (int)GetSessionValue(); } 
    set { SetSessionValue(value); } 
} 
+0

Ta odpowiedź jest najlepszym sposobem, ponieważ działa w czasie kompilacji, a nie w czasie wykonywania. – EvilTak