Retrieving Property name from lambda expression

前端 未结 21 1703
迷失自我
迷失自我 2020-11-21 11:12

Is there a better way to get the Property name when passed in via a lambda expression? Here is what i currently have.

eg.

GetSortingInfo         


        
21条回答
  •  旧巷少年郎
    2020-11-21 12:04

    I have done the INotifyPropertyChanged implementation similar to the method below. Here the properties are stored in a dictionary in the base class shown below. It is of course not always desirable to use inheritance, but for view models I think it is acceptable and gives very clean property references in the view model classes.

    public class PhotoDetailsViewModel
        : PropertyChangedNotifierBase
    {
        public bool IsLoading
        {
            get { return GetValue(x => x.IsLoading); }
            set { SetPropertyValue(x => x.IsLoading, value); }
        }
    
        public string PendingOperation
        {
            get { return GetValue(x => x.PendingOperation); }
            set { SetPropertyValue(x => x.PendingOperation, value); }
        }
    
        public PhotoViewModel Photo
        {
            get { return GetValue(x => x.Photo); }
            set { SetPropertyValue(x => x.Photo, value); }
        }
    }
    

    The somewhat more complex base class is shown below. It handles the translation from lambda expression to property name. Note that the properties are really pseudo properties since only the names are used. But it will appear transparent to the view model and references to the properties on the view model.

    public class PropertyChangedNotifierBase : INotifyPropertyChanged
    {
        readonly Dictionary _properties = new Dictionary();
    
        protected U GetValue(Expression> property)
        {
            var propertyName = GetPropertyName(property);
    
            return GetValue(propertyName);
        }
    
        private U GetValue(string propertyName)
        {
            object value;
    
            if (!_properties.TryGetValue(propertyName, out value))
            {
                return default(U);
            }
    
            return (U)value;
        }
    
        protected void SetPropertyValue(Expression> property, U value)
        {
            var propertyName = GetPropertyName(property);
    
            var oldValue = GetValue(propertyName);
    
            if (Object.ReferenceEquals(oldValue, value))
            {
                return;
            }
            _properties[propertyName] = value;
    
            RaisePropertyChangedEvent(propertyName);
        }
    
        protected void RaisePropertyChangedEvent(Expression> property)
        {
            var name = GetPropertyName(property);
            RaisePropertyChangedEvent(name);
        }
    
        protected void RaisePropertyChangedEvent(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        private static string GetPropertyName(Expression> property)
        {
            if (property == null)
            {
                throw new NullReferenceException("property");
            }
    
            var lambda = property as LambdaExpression;
    
            var memberAssignment = (MemberExpression) lambda.Body;
            return memberAssignment.Member.Name;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

提交回复
热议问题