C# 物业信息的优势是什么?

C# 物业信息的优势是什么?,c#,c#-4.0,c#-3.0,expression,c#-2.0,C#,C# 4.0,C# 3.0,Expression,C# 2.0,在.NETFramework3.5中,我们可以使用下面提到的代码获取属性信息 using System; using System.Linq.Expressions; using System.Reflection; class Foo { public string Bar { get; set; } } static class Program { static void Main() { PropertyInfo prop = PropertyHe

在.NETFramework3.5中,我们可以使用下面提到的代码获取属性信息

using System;
using System.Linq.Expressions;
using System.Reflection;

class Foo
{
    public string Bar { get; set; }
}
static class Program
{
    static void Main()
    {
        PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar);
    }
}
public static class PropertyHelper<T>
{
    public static PropertyInfo GetProperty<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (PropertyInfo)((MemberExpression)body).Member;
            default:
                throw new InvalidOperationException();
        }
    }
}
这也可以通过创建类的实例并访问属性成员来实现。那么属性信息的优点是什么呢?

PropertyInfo用于获取类的属性信息。不需要创建实例。优点是它消除了输入错误的可能性

表达式是完全不同的概念,在内部使用反射。表达式用于将方法体表示为树结构。这允许在运行时灵活地创建/调整方法定义

类利用表达式的这种功能在远程源上构建/执行动态查询

例如, 考虑IntIfyPrimyType更改的接口。它用于属性更改通知

通常的实现将属性名作为字符串参数。因此,在运行时会检测到键入错误。重构也会破坏代码,尽管智能重构工具会处理这一点

    void RaisePropertyChanged(PropertyChangedEventArgs args)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public string Name
    {
        set
        {
            _name = value;
            RaisePropertyChanged("Name"); // Property name is specified as string
        }
    }
一个更好的实现不是性能有效的,而是将属性名作为表达式

PropertyInfo用于获取类的属性信息。不需要创建实例。优点是它消除了输入错误的可能性

表达式是完全不同的概念,在内部使用反射。表达式用于将方法体表示为树结构。这允许在运行时灵活地创建/调整方法定义

类利用表达式的这种功能在远程源上构建/执行动态查询

例如, 考虑IntIfyPrimyType更改的接口。它用于属性更改通知

通常的实现将属性名作为字符串参数。因此,在运行时会检测到键入错误。重构也会破坏代码,尽管智能重构工具会处理这一点

    void RaisePropertyChanged(PropertyChangedEventArgs args)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public string Name
    {
        set
        {
            _name = value;
            RaisePropertyChanged("Name"); // Property name is specified as string
        }
    }
一个更好的实现不是性能有效的,而是将属性名作为表达式


通过解析表达式获得PropertyInfo的优点是,它提供了编译时检查,并提供了更好的重构支持

例如,如果您将属性的名称从Bar更改为Barr,那么代码将不再编译,从而允许您捕获无效的成员访问错误,而无需实际运行应用程序

如果您事先知道需要访问哪一个确切的属性,那么表达式就是最好的选择

我发现表达式在数据绑定场景中特别有用,例如,需要指定要绑定到网格列或列表控件的属性的名称。在这种情况下使用表达式可以降低维护成本

下面是一个使用表达式对自己的PropertyHelper类执行网格列格式化的示例

跳转到GridForm.FormatGrid以查看重要位

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows.Forms;

namespace ExpressionSample
{
    public class TestEntity
    {
        public int ID { get; set; }
        public string Text { get; set; }
        public decimal Money { get; set; }
    }

    public partial class GridForm : Form
    {
        public GridForm()
        {
            this.InitializeComponent();
        }

        private void GridForm_Load(object sender, EventArgs e)
        {
            this.FillGrid();
            this.FormatGrid();
        }

        private void FillGrid()
        {
            this.DataGridView.DataSource = TestDataProducer.GetTestData();
        }

        private void FormatGrid()
        {
            var redCellStyle = new DataGridViewCellStyle() { ForeColor = Color.Red };
            var moneyCellStyle = new DataGridViewCellStyle() { Format = "$###,###,##0.00" };

            this.GridColumn(e => e.ID).Visible = false;
            this.GridColumn(e => e.Text).DefaultCellStyle = redCellStyle;
            this.GridColumn(e => e.Money).DefaultCellStyle = moneyCellStyle;
        }

        private DataGridViewColumn GridColumn<TProperty>(Expression<Func<TestEntity, TProperty>> expr)
        {
            var propInfo = PropertyHelper<TestEntity>.GetProperty(expr);
            var column = this.DataGridView.Columns[propInfo.Name];

            return column;
        }
    }

    public static class PropertyHelper<T>
    {
        public static PropertyInfo GetProperty<TValue>(
            Expression<Func<T, TValue>> selector)
        {
            Expression body = selector;
            if (body is LambdaExpression)
            {
                body = ((LambdaExpression)body).Body;
            }
            switch (body.NodeType)
            {
                case ExpressionType.MemberAccess:
                    return (PropertyInfo)((MemberExpression)body).Member;
                default:
                    throw new InvalidOperationException();
            }
        }
    }

    public static class TestDataProducer
    {
        public static IList<TestEntity> GetTestData()
        {
            var entities = new List<TestEntity>();

            for (var i = 1; i <= 10; i++)
            {
                var testEntity = new TestEntity {
                    ID = i,
                    Text = "Entity " + i.ToString(),
                    Money = i * 100m
                };

                entities.Add(testEntity);
            }

            return entities;
        }
    }
}

通过解析表达式获得PropertyInfo的优点是,它提供了编译时检查,并提供了更好的重构支持

例如,如果您将属性的名称从Bar更改为Barr,那么代码将不再编译,从而允许您捕获无效的成员访问错误,而无需实际运行应用程序

如果您事先知道需要访问哪一个确切的属性,那么表达式就是最好的选择

我发现表达式在数据绑定场景中特别有用,例如,需要指定要绑定到网格列或列表控件的属性的名称。在这种情况下使用表达式可以降低维护成本

下面是一个使用表达式对自己的PropertyHelper类执行网格列格式化的示例

跳转到GridForm.FormatGrid以查看重要位

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows.Forms;

namespace ExpressionSample
{
    public class TestEntity
    {
        public int ID { get; set; }
        public string Text { get; set; }
        public decimal Money { get; set; }
    }

    public partial class GridForm : Form
    {
        public GridForm()
        {
            this.InitializeComponent();
        }

        private void GridForm_Load(object sender, EventArgs e)
        {
            this.FillGrid();
            this.FormatGrid();
        }

        private void FillGrid()
        {
            this.DataGridView.DataSource = TestDataProducer.GetTestData();
        }

        private void FormatGrid()
        {
            var redCellStyle = new DataGridViewCellStyle() { ForeColor = Color.Red };
            var moneyCellStyle = new DataGridViewCellStyle() { Format = "$###,###,##0.00" };

            this.GridColumn(e => e.ID).Visible = false;
            this.GridColumn(e => e.Text).DefaultCellStyle = redCellStyle;
            this.GridColumn(e => e.Money).DefaultCellStyle = moneyCellStyle;
        }

        private DataGridViewColumn GridColumn<TProperty>(Expression<Func<TestEntity, TProperty>> expr)
        {
            var propInfo = PropertyHelper<TestEntity>.GetProperty(expr);
            var column = this.DataGridView.Columns[propInfo.Name];

            return column;
        }
    }

    public static class PropertyHelper<T>
    {
        public static PropertyInfo GetProperty<TValue>(
            Expression<Func<T, TValue>> selector)
        {
            Expression body = selector;
            if (body is LambdaExpression)
            {
                body = ((LambdaExpression)body).Body;
            }
            switch (body.NodeType)
            {
                case ExpressionType.MemberAccess:
                    return (PropertyInfo)((MemberExpression)body).Member;
                default:
                    throw new InvalidOperationException();
            }
        }
    }

    public static class TestDataProducer
    {
        public static IList<TestEntity> GetTestData()
        {
            var entities = new List<TestEntity>();

            for (var i = 1; i <= 10; i++)
            {
                var testEntity = new TestEntity {
                    ID = i,
                    Text = "Entity " + i.ToString(),
                    Money = i * 100m
                };

                entities.Add(testEntity);
            }

            return entities;
        }
    }
}

请参见使用您引用的示例代码,在本上下文中使用表达式树主要是为了在希望获取属性信息时避免在代码中硬编码属性名称。这在简化重构方面有很大帮助。请参阅使用您引用的示例代码,在本文中使用表达式树主要是为了避免在代码中硬编码属性名称,以获取属性信息。这对简化重构有很大帮助。实际上,这是一种提取属性信息的方法。另一条路在这里。。。TypeOfMyCassType.GetPropertyPropertyName。使用反射概念我们可以面对任何内存泄漏问题吗?@Needhelp我相信这至少可以防止您在GetProperty方法中指定PropertyName时输入错误。@Needhelp,内存泄漏问题->否。未实现IDisposable,这提示它不使用本机资源。您能告诉我们应该在哪种情况下使用它吗?你能分享一些例子吗?实际上,这是一种提取财产信息的方法。
另一条路在这里。。。TypeOfMyCassType.GetPropertyPropertyName。使用反射概念我们可以面对任何内存泄漏问题吗?@Needhelp我相信这至少可以防止您在GetProperty方法中指定PropertyName时输入错误。@Needhelp,内存泄漏问题->否。未实现IDisposable,这提示它不使用本机资源。您能告诉我们应该在哪种情况下使用它吗?你能分享一些例子吗?你能告诉我们在什么情况下应该使用它吗?你能告诉我们在什么情况下应该使用它吗?