帮助定义通用方法以及表达式树参数

发布于 2024-11-02 02:06:12 字数 615 浏览 1 评论 0原文

假设我有:

class Person
{
[ColumnAttribute("ID"]
    public int Id;
[ColumnAttribute("Name"]
public string Name;
[ColumnAttribute("DateOfBirth"]
    public date BirthDate;
}

我想创建一个将被调用的方法,

GetPropertyColumn<Person>(e=>e.Name)

此方法将返回由 ColumnAttribute 属性定义的字符串。
问题是我无法定义这个方法。 我尝试过

public string GetPropertyColumn<T,U>(Expression<Func<T, U>> Lamda)

,但问题是我只能指定 T 而不能指定 U,所以它不起作用。
有什么帮助吗?
谢谢

编辑:

感谢您的回答,但我得到了很多答案,您需要实例化 Person,但我不想这样做。
因为我只想知道给定类中定义的属性的列。

Suppose I have:

class Person
{
[ColumnAttribute("ID"]
    public int Id;
[ColumnAttribute("Name"]
public string Name;
[ColumnAttribute("DateOfBirth"]
    public date BirthDate;
}

i want to create a method that will be called as following

GetPropertyColumn<Person>(e=>e.Name)

this method will return a string that is defined by the ColumnAttribute attribute.
the problem is that i am not able to define this method.
i tried

public string GetPropertyColumn<T,U>(Expression<Func<T, U>> Lamda)

but the problem is that i can only specify the T and not the U so its not working.
any help?
thanks

Edit:

thanks for the answers but i got a lot of answers in which you need to instantinate Person but i dont want to.
because i only want to know the column given a property defined inside a Class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

流绪微梦 2024-11-09 02:06:12

如果您有一个具有 2 个泛型类型(T 和 U)的泛型方法,则两者都将被指定,或者两者都将被推断。如果这不可能,请考虑采用 Func 的表达式(删除 U),并在运行时检查表达式树时从表达式树中删除转换/转换节点。您还可以采取一些措施来推断这两种类型,但这可能需要更多的重构。

If you have a generic method with 2 generic types (T and U) then both most be specified, or both most be inferred. If that isn't possible, consider an expression taking Func<T,object> (remove U), and remove the cast/convert node from the expression tree when inspecting it at runtime. You can also do things to make both types inferred, but that may need more of a refactor.

世界等同你 2024-11-09 02:06:12

[编辑 3]

    public static string GetPropertyColumn<T>(Expression<Func<T,object>> f)
    {
        Type t = typeof(T);

        MemberExpression memberExpression = null;

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

        string name = memberExpression.Member.Name;

        System.Reflection.FieldInfo fi = t.GetField(name);
        object[] attrs = fi.GetCustomAttributes(true);

        foreach (var attr in attrs)
        {
            ColumnAttribute columnAttr = attr as ColumnAttribute;
            if (columnAttr != null)
            {
                return columnAttr.Name;
            }
        }

        return string.Empty;
    }

使用:

Console.WriteLine(GetPropertyColumn<Person>(e => e.Name));

[EDIT 3]

    public static string GetPropertyColumn<T>(Expression<Func<T,object>> f)
    {
        Type t = typeof(T);

        MemberExpression memberExpression = null;

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

        string name = memberExpression.Member.Name;

        System.Reflection.FieldInfo fi = t.GetField(name);
        object[] attrs = fi.GetCustomAttributes(true);

        foreach (var attr in attrs)
        {
            ColumnAttribute columnAttr = attr as ColumnAttribute;
            if (columnAttr != null)
            {
                return columnAttr.Name;
            }
        }

        return string.Empty;
    }

using:

Console.WriteLine(GetPropertyColumn<Person>(e => e.Name));
素年丶 2024-11-09 02:06:12

使其成为扩展方法:

static class ExtensionMethods
{
    public static string GetPropertyColumn<T,U>(this T obj, Expression<Func<T, U>> selector)
    {
        ... // whatever
    }
}

并按如下方式使用它:

Person person = ...
string propertyColumn = person.GetPropertyColumn(p => p.Name);

您不需要指定 T,因为它是从第一个参数推断出来的,也不需要指定 U,因为它是从 lambda 的返回类型推断出来的

请注意,您不需要将其定义为扩展方法,它也可以是普通方法。然后你会像这样使用它:

Person person = ...
string propertyColumn = GetPropertyColumn(person, p => p.Name);

Make it an extension method:

static class ExtensionMethods
{
    public static string GetPropertyColumn<T,U>(this T obj, Expression<Func<T, U>> selector)
    {
        ... // whatever
    }
}

And use it as follows:

Person person = ...
string propertyColumn = person.GetPropertyColumn(p => p.Name);

You don't need to specify T, because it's inferred from the first parameter, and you don't need to specify U either because it is inferred from the return type of the lambda

Note that you don't need to define it as an extension method, it could also be a normal method. You would then use it like that:

Person person = ...
string propertyColumn = GetPropertyColumn(person, p => p.Name);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文