C# C使用泛型类型简化构造函数中的属性选择器

C# C使用泛型类型简化构造函数中的属性选择器,c#,C#,如果可能的话,我想简化一些代码 当前构造函数T在外部类型中定义的范围内 public Column(string propertyName) { PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName); _ = propertyInfo ?? throw new ArgumentException(message: $"Property {propertyName} does not exist on {t

如果可能的话,我想简化一些代码

当前构造函数T在外部类型中定义的范围内

public Column(string propertyName)
{
    PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);

    _ = propertyInfo ?? throw new ArgumentException(message: $"Property {propertyName} does not exist on {typeof(T).Name}");

    ...
}
我想知道是否可以将属性设置为Lambda表达式或选择泛型类型T的属性

这当然是为了使我们的开发更容易,错误更少

当前使用

新建DataTable.ColumnnameofsomeClass.someProperty

我想做一些类似的事情:

新建DataTable.ColumnsomeClass.someProperty,但不声明新的someClass


new DataTable.Columnt=>t.someProperty

您可以使用以下方法从表达式中提取属性名称

    public static PropertyInfo GetAccessedMemberInfo<T>(this Expression<T> expression)
    {
        MemberExpression? memberExpression = null;

        if (expression.Body.NodeType == ExpressionType.Convert)
        {
            memberExpression = ((UnaryExpression)expression.Body).Operand as MemberExpression;
        }
        else if (expression.Body.NodeType == ExpressionType.MemberAccess)
        {
            memberExpression = expression.Body as MemberExpression;
        }

        if (memberExpression == null)
        {
            throw new ArgumentException("Not a member access", "expression");
        }

        return memberExpression.Member as PropertyInfo ?? throw new Exception();
    }
然后像这样使用它

public Column(Expression<Func<T, object>> prop)
{
    PropertyInfo propertyInfo = prop.GetAccessedMemberInfo();
}

new DataTable<someClass>.Column(t = > t.someProperty)

前面的答案更完整,支持更多场景,但也更复杂

如果您不需要这种灵活性,这将强制您使用强类型,并确保构造函数从不抛出

namespace ConsoleApp1
{

    public class Column<T, TProperty>
    {
        Func<T, TProperty> functionToBeApplied;

        // Pass a function, it can never throw
        public Column(Func<T, TProperty> functionToBeApplied)
        {
            this.functionToBeApplied = functionToBeApplied;
        }

        // Apply the function to the object
        public string GetPropertyAsString(T obj)
        {
            TProperty property = functionToBeApplied(obj);
            return property.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            var column = new Column<string, int>(x => x.Length);

            Console.WriteLine($"Size of string is {column.GetPropertyAsString("this is my object")}");
        }
    }
}

您可以接受Func或表达式。您想对属性做什么?要展开:是的,您绝对可以。但您采取的路线取决于您是否需要PropertyInfo,或者是否可以使用直接获取/设置该属性的委托。这就是@JohnathanBarclay要求提供更多信息的原因。一旦我们有了它,我们可以给你一个具体的答案。你知道DataTable.Column是一个方法,而不是构造函数,这是你在第一个代码示例中介绍的东西吗?@JohnathanBarclay,我只需要获取PropertyInfo。我有一些自定义属性,这些属性包含构建数据表时使用的基本列信息。