C# 属性内容提取

C# 属性内容提取,c#,reflection,properties,attributes,C#,Reflection,Properties,Attributes,我试图简化从属性中提取数据的代码 属性: [AttributeUsage(AttributeTargets.Property)] class NameAttribute : Attribute { public string Name { get; } public ColumnAttribute(string name) { Name = name; } } 属性内容提取代码(已删除空检查): 呼叫样本: var name = GetName

我试图简化从属性中提取数据的代码

属性:

[AttributeUsage(AttributeTargets.Property)]
class NameAttribute : Attribute
{
    public string Name { get; }

    public ColumnAttribute(string name)
    {
        Name = name;
    }
}
属性内容提取代码(已删除空检查):

呼叫样本:

var name = GetName<TestClass>(nameof(TestClass.NamedProperty))
var name=GetName(nameof(TestClass.NamedProperty))
是否可以重写属性内容提取方法以简化/缩短其调用。它太长了,对我来说太不方便了


类似的东西会很好,但我什么也没找到。

您的语法已经很短了。唯一的冗余信息是类名,其他所有信息都是必需的,它不会变得更短。您可以在调用中使用更短的语法,如下所示,删除类名的冗余。然而,这需要付出代价,或者需要更复杂的实现。由您决定是否值得:

namespace ConsoleApp2
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    static class Program
    {
        // your old method:
        public static string GetName<T>(string propName)
        {
            var propertyInfo = typeof(T).GetProperty(propName);

            var nameAttribute = propertyInfo.GetCustomAttribute(typeof(NameAttribute)) as NameAttribute;

            return nameAttribute.Name;
        }

        // new syntax method. Still calls your old method under the hood.
        public static string GetName<TClass, TProperty>(Expression<Func<TClass, TProperty>> action)
        {
            MemberExpression expression = action.Body as MemberExpression;
            return GetName<TClass>(expression.Member.Name);
        }
        
        static void Main()
        {
            // you had to type "TestClass" twice
            var name = GetName<TestClass>(nameof(TestClass.NamedProperty));

            // slightly less intuitive, but no redundant information anymore
            var name2 = GetName((TestClass x) => x.NamedProperty);

            Console.WriteLine(name);
            Console.WriteLine(name2);
            Console.ReadLine();
        }
    }

    [AttributeUsage(AttributeTargets.Property)]
    class NameAttribute : Attribute
    {
        public string Name { get; }

        public NameAttribute(string name)
        {
            this.Name = name;
        }
    }
    
    class TestClass
    {
        [Name("SomeName")]
        public object NamedProperty { get; set; }
    }
}
namespace ConsoleApp2
{
使用制度;
使用System.Linq.Expressions;
运用系统反思;
静态类程序
{
//您的旧方法:
公共静态字符串GetName(字符串propName)
{
var propertyInfo=typeof(T).GetProperty(propName);
var nameAttribute=propertyInfo.GetCustomAttribute(typeof(nameAttribute))作为nameAttribute;
返回nameAttribute.Name;
}
//新语法方法。仍然在幕后调用旧方法。
公共静态字符串GetName(表达式操作)
{
MemberExpression=action.Body作为MemberExpression;
返回GetName(expression.Member.Name);
}
静态void Main()
{
//您必须键入“TestClass”两次
var name=GetName(nameof(TestClass.NamedProperty));
//稍微不那么直观,但不再有多余的信息
var name2=GetName((TestClass x)=>x.NamedProperty);
Console.WriteLine(名称);
控制台写入线(名称2);
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.Property)]
类名属性:属性
{
公共字符串名称{get;}
公共名称属性(字符串名称)
{
this.Name=Name;
}
}
类TestClass
{
[姓名(“某人姓名”)]
公共对象名称属性{get;set;}
}
}
输出相同:

名字

名字


你的语法已经很短了。唯一的冗余信息是类名,其他所有信息都是必需的,它不会变得更短。您可以在调用中使用更短的语法,如下所示,删除类名的冗余。然而,这需要付出代价,或者需要更复杂的实现。由您决定是否值得:

namespace ConsoleApp2
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    static class Program
    {
        // your old method:
        public static string GetName<T>(string propName)
        {
            var propertyInfo = typeof(T).GetProperty(propName);

            var nameAttribute = propertyInfo.GetCustomAttribute(typeof(NameAttribute)) as NameAttribute;

            return nameAttribute.Name;
        }

        // new syntax method. Still calls your old method under the hood.
        public static string GetName<TClass, TProperty>(Expression<Func<TClass, TProperty>> action)
        {
            MemberExpression expression = action.Body as MemberExpression;
            return GetName<TClass>(expression.Member.Name);
        }
        
        static void Main()
        {
            // you had to type "TestClass" twice
            var name = GetName<TestClass>(nameof(TestClass.NamedProperty));

            // slightly less intuitive, but no redundant information anymore
            var name2 = GetName((TestClass x) => x.NamedProperty);

            Console.WriteLine(name);
            Console.WriteLine(name2);
            Console.ReadLine();
        }
    }

    [AttributeUsage(AttributeTargets.Property)]
    class NameAttribute : Attribute
    {
        public string Name { get; }

        public NameAttribute(string name)
        {
            this.Name = name;
        }
    }
    
    class TestClass
    {
        [Name("SomeName")]
        public object NamedProperty { get; set; }
    }
}
namespace ConsoleApp2
{
使用制度;
使用System.Linq.Expressions;
运用系统反思;
静态类程序
{
//您的旧方法:
公共静态字符串GetName(字符串propName)
{
var propertyInfo=typeof(T).GetProperty(propName);
var nameAttribute=propertyInfo.GetCustomAttribute(typeof(nameAttribute))作为nameAttribute;
返回nameAttribute.Name;
}
//新语法方法。仍然在幕后调用旧方法。
公共静态字符串GetName(表达式操作)
{
MemberExpression=action.Body作为MemberExpression;
返回GetName(expression.Member.Name);
}
静态void Main()
{
//您必须键入“TestClass”两次
var name=GetName(nameof(TestClass.NamedProperty));
//稍微不那么直观,但不再有多余的信息
var name2=GetName((TestClass x)=>x.NamedProperty);
Console.WriteLine(名称);
控制台写入线(名称2);
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.Property)]
类名属性:属性
{
公共字符串名称{get;}
公共名称属性(字符串名称)
{
this.Name=Name;
}
}
类TestClass
{
[姓名(“某人姓名”)]
公共对象名称属性{get;set;}
}
}
输出相同:

名字

名字


meI看起来没问题,我在寻找一种方法将其插入字符串,每个字符串2..5个调用,但当前调用语法太长,它看起来没问题,meI在寻找一种方法将其插入字符串,每个字符串2..5个调用,但当前调用语法太长
namespace ConsoleApp2
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    static class Program
    {
        // your old method:
        public static string GetName<T>(string propName)
        {
            var propertyInfo = typeof(T).GetProperty(propName);

            var nameAttribute = propertyInfo.GetCustomAttribute(typeof(NameAttribute)) as NameAttribute;

            return nameAttribute.Name;
        }

        // new syntax method. Still calls your old method under the hood.
        public static string GetName<TClass, TProperty>(Expression<Func<TClass, TProperty>> action)
        {
            MemberExpression expression = action.Body as MemberExpression;
            return GetName<TClass>(expression.Member.Name);
        }
        
        static void Main()
        {
            // you had to type "TestClass" twice
            var name = GetName<TestClass>(nameof(TestClass.NamedProperty));

            // slightly less intuitive, but no redundant information anymore
            var name2 = GetName((TestClass x) => x.NamedProperty);

            Console.WriteLine(name);
            Console.WriteLine(name2);
            Console.ReadLine();
        }
    }

    [AttributeUsage(AttributeTargets.Property)]
    class NameAttribute : Attribute
    {
        public string Name { get; }

        public NameAttribute(string name)
        {
            this.Name = name;
        }
    }
    
    class TestClass
    {
        [Name("SomeName")]
        public object NamedProperty { get; set; }
    }
}