Laden...

Mit Reflection rausfinden, in welchem Property sich aufgerufene Methode befindet

Erstellt von Briefkasten vor 15 Jahren Letzter Beitrag vor 14 Jahren 2.056 Views
Briefkasten Themenstarter:in
446 Beiträge seit 2004
vor 15 Jahren
Mit Reflection rausfinden, in welchem Property sich aufgerufene Methode befindet

Hallo,

gibt es eine möglichkeit, herauszufinden, in welcher property man sich gerade befindet.

z.B.

public string FirstName
        {
            get
            {
                return _FristName;
            }
            set
            {
                _FristName = value;
                string propname = PersonPrivatFunctions.GetPropertyName();
                NotifyPropertyChanged( propname  );

            }
        }

Hat jemand eine idee? Einen ansatz habe ich schon gefunden. http://www.csharp-examples.net/reflection-property-names/
Nur bekomme ich so alle propertynames zurück. Hat jemand eine idee?

Schaut mal im IRC vorbei:
Server: https://libera.chat/ ##chsarp

179 Beiträge seit 2006
vor 15 Jahren

Hi,

Ich hatte selbst mal versucht, das InotifyPropertyChanged auf basis dieses Threads zu verallgemeinern. Ich habe dabei den Property-Name mittels folgenden Code ermittelt.
Allerdings habe ich diese Methode wieder verworfen, da sie ca. !!500!! mal länger dauert.


    public class Test : INotifyPropertyChanged, INotifyPropertyChanging {
        public event PropertyChangingEventHandler PropertyChanging;
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
            if (PropertyChanged != null) PropertyChanged(this, e);
        }
        protected virtual void OnPropertyChanging(PropertyChangingEventArgs e) {
            if (PropertyChanging != null) PropertyChanging(this, e);
        }

        protected bool Notify<T>(ref T oldValue, T newValue) {
            StackTrace trc = new StackTrace();
            MethodBase calling = trc.GetFrame(1).GetMethod();

            if (!calling.IsSpecialName || !calling.Name.StartsWith("set_"))
                throw new Exception("Calling Method is not a setter of a Property");

            PropertyInfo pi = this.GetType().GetProperty(calling.Name.Substring(4));
            return Notify(pi.Name, ref oldValue, newValue);
        }
        protected bool Notify<T>(string propertyName, ref T oldValue, T newValue) {
            if (oldValue == null && newValue == null) {
                return false;
            }
            if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue)) {
                OnPropertyChanging(new PropertyChangingEventArgs(propertyName));
                oldValue = newValue;
                OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
                return true;
            }
            return false;
        }

        private int m_A;
        public int A {
            get { return m_A; }
            set { Notify(ref m_A, value); }
        }

        private int m_B;
        public int B {
            get { return m_B; }
            set { Notify("C", ref m_B, value); }
        }

    }

1.665 Beiträge seit 2006
vor 15 Jahren

Was hast du genau vor?
Evtl. lässt sich dein Problem dann anders lösen.

F
10.010 Beiträge seit 2004
vor 15 Jahren

Das problem dabei ist allerdings, das du dann niemals im Release Modus compilieren.

Denn sobald der JIT Compiler anfängt zu optimieren, kann er Properties
inlinen, und schon ist dein Code hinfällig.

Aber vielleicht solltest Du dir mal einen der vielen Dynamischen Proxies anschauen.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Briefkasten,

der Artikel [Artikel] Attribute zur Prüfung von Properties verwenden enthält Code für die Ermittlung der Property inkl. Diskussion über den besten Weg und einer Lösung für das Inlining/Releasmode-Problem.

herbivore

5.942 Beiträge seit 2005
vor 15 Jahren

Hallo zusammen

Wie wäre sowas mit AOP?


[NotifyPropertyChanged]
public class Person
{
    public string Name { get; set; }
}

oder


[NotifyPropertyChanged("Age")]
public class Person
{
    public string Name { get; set; }
    public string Age { get; set; }
}

So kann der zusätzliche Code beim kompilieren automatisch generiert werden.
Der optionale Parameter des Attributes wäre dann bspw. "excluded properties".

Ich habe irgendwo auch eine Lösung mit C# gesehen, ohne den Eigenschaftsnamen per String zu übergeben, aber das finde ich partou im Moment nicht mehr.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

3.971 Beiträge seit 2006
vor 15 Jahren

Hallo Peter,
ist das NotifyPropertyChanged-Attribute von PostSharp?

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

5.942 Beiträge seit 2005
vor 15 Jahren

Salute kleines_eichoernchen

ist das NotifyPropertyChanged-Attribute von PostSharp?){gray}

Ich denke nicht dass es das gibt, evt. aber schon.
Es war nur eine Idee von mir, das bspw. per PostSharp zu implementierten, möglich sollte es auf jeden Fall sein.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Briefkasten Themenstarter:in
446 Beiträge seit 2004
vor 14 Jahren

Hi,

wenn auch spät. Ich hab es jetzt mittels einer Extension gelöst.

        public static string GetMemberName(Expression<Func<TEntity, TProperty>> projection)
        {
            return ((MemberExpression)projection.Body).Member.Name;
        }

//Der geposted Code ist nicht die Extension nur wie die Extension Codemäßig aussieht.

Schaut mal im IRC vorbei:
Server: https://libera.chat/ ##chsarp