使用System.Attribute类
-
21-08-2019 - |
题
我有我自己的状况下使用System.Attribute类似乎(乍)是一个好主意。
我在我的申请待打印的对象,并且我每个属性(或只是一个字符串之前)之前需要一个标签。我可以把硬编码等每个属性:
Console.WriteLine("Color:"+obj.color);
Console.WriteLine("Size:"+obj.size);
和等为每个属性。但是,而不是它,我试图创造一个并不需要这个“标签”被硬编码代码,这样我就可以动态地打印每个属性。
我得到类似的东西,用System.Attribute类:
public class MyObject
{
[MyCustomLabel("Color:")]
public string Color;
[MyCustomLabel("Size:")]
public string Size;
//etc...
}
所以,这才是我的问题:抓取这个属性的值是不可能的,但因为我不得不使用一些反射它是不友善。
我真的不害怕使用反射,但它似乎是我使用的属性,它不是为创建的东西。
我不知道是使用属性最好的地方,如果这是真的使用它的情况。
解决方案
特性和反射相随。一些编译器/运行属性之外,就没有办法用了反映在代码中使用它们。
这是说,你的做法是合理的,你可能想看看在System.ComponentModel
命名空间,其有许多类有用的元数据来装饰性的属性。
其他提示
您是在正确的轨道上。
此外,有一个[DisplayName的]属性用于此目的已经量身定做,自2.0以来一直在.NET。
http://msdn.microsoft.com/en -us /库/ system.componentmodel.displaynameattribute.aspx
如果你只是写到控制台,即它是调试风格输出,那么你想要的是错字/复制粘贴错误的机率很少。
这是在引擎盖下混乱,但是高度有效的在调用点:
public static void WriteNameAndValue<T,TValue>(
this TextWriter tw, T t,
Expression<Func<T, TValue>> getter)
{
var memberExpression = getter.Body as MemberExpression;
if (memberExpression == null)
throw new ArgumentException("missing body!");
var member = memberExpression.Member;
tw.Write(member.Name);
tw.Write(": ");
if (member is FieldInfo)
{
tw.Write(((FieldInfo)member).GetValue(t));
}
else if (member is PropertyInfo)
{
tw.Write(((PropertyInfo)member).GetValue(t, null));
}
}
public static void WriteNameAndValueLine<T,TValue>(
this TextWriter tw, T t,
Expression<Func<T, TValue>> getter)
{
WriteNameAndValue<T,TValue>(tw, t, getter);
tw.WriteLine();
}
然后可以写
t.Foo = "bar";
t.Bar = 32.5;
Console.Out.WriteNameAndValueLine(t, x => x.Foo);
Console.Out.WriteNameAndValueLine(t, x => x.Bar);
// output
// Foo: bar
// Bar: 32.5
如果您希望这通过资源,并考虑本地化,你可以这样做,但我会考虑其他,更规范,而不是办法,如果这是一个可能需要在运行时更可配置的。
P.S。如果你想获得幻想你可以替换
的字段信息/开关的PropertyInfotw.Write(getter.Compile()(t));
然后你可以在表达检查的MethodInfo以及(或允许任意的lambda表达式和刚刚插入的行号或其他一些通用的文字。我建议不要走这路线,使用已经是混乱也可能会造成不必要的加载在什么应该是一个简单测井方法。
这是序列化是如何工作的,所以我会说,你的做法是合理的。你可以处理这个另一种方式是创建PropertyNames和他们的头衔的字典,然后查找标题基于属性名称。
我有一个对象在我的应用将被打印,并且我需要每个属性之前的标签(或之前的字符串的话)。
为什么你认为你的情况使用属性吗?你在哪里打印该对象在应用程序中。
也许只是实施的ToString 在你的对象(S)点击 E.g。
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("PropertyX: ");
sb.AppendLine(this.PropertyX);
// get string from resource file
sb.Append(Resources.FileName);
sb.Append(": ");
sb.AppendLine(this.FileName);
sb.Append("Number: ");
sb.AppendLine(this.Number.ToString());
return sb.ToString();
}