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; }
}
}