Fáb*_*nes 4 c# enums custom-attributes
在这里,我花了一些时间来了解有关C#的更多信息,因此我决定研究自定义属性,并且在分配给Enums时发现它们非常有用.
所以我为Enum编写了一些扩展方法来很容易地检索这些属性,比如:DemoEnum.Value1.GetAttribute<EnumNote>().
过了一会儿,我想如果每个自定义属性都有对它所分配的枚举的引用,这将是一个不错的主意.我想是个不错的主意,所以我继续这样做:
首先,我EnumAttribute为自定义属性编写了一个基System.Attribute类,当然继承了该类.这个基类只是第一个草图,我打算将它扩展为特别适合它将接收的每种类型的枚举,但到目前为止这已足够.
public class EnumAttribute : Attribute
{
public EnumInfo Enum { get; internal set; }
public EnumAttribute(Enum Enum)
{
this.Enum = new EnumInfo(Enum);
}
public class EnumInfo
{
private Enum _value;
private Type _type;
private FieldInfo _details;
public Enum Value { get { return _value; } }
public Type Type { get { return _type; } }
public FieldInfo Details { get { return _details; } }
public EnumInfo(Enum value)
{
_value = value;
_type = value.GetType();
_details = _type.GetField(System.Enum.GetName(_type, value));
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在每个自定义属性都必须从此类继承EnumAttribute.结果例如在类中EnumNote:
public class EnumNote : EnumAttribute
{
private string _note = string.Empty;
public string Note { get { return _note; } }
public EnumNote(Enum Enum, string Note)
: base(Enum)
{
_note = Note;
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好,Visual Studio代码分析和编译器报告都没有.
但是当我定义一个Enum时,例如:
public enum DemoEnum
{
[EnumNote(DemoEnum.Value1, "Some special note about Enum Value1.")]
Value1 = 1,
[EnumNote(DemoEnum.Value2, "Some other special note about Enum Value2.")]
Value2 = 2
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,VS报告每个EnumNote构造函数的第一个参数如下:
属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式.
基本上是说DemoEnum.Value1和DemoEnum.Value2不保持常量值.我是对的?
无论如何,这个错误让我感到困惑,因为这个Enum是硬编码的,正如你所看到的,编译器甚至不必为每个枚举分配一个值,因为我已经自己做了.
这当然会带来一个问题,我缺少什么或误解,以及我应该如何实现提供每个EnumNote被分配到的枚举的引用的目标?
谢谢.
更新:
重新审视之后,我理解为什么VS报告枚举不是一个常量表达式,那是因为我指的是某些东西:DemoEnum.Value1在某一点上,他还没有完成对第DemoEnum一个定义的定义Value1地点.但是没有关于如何继续我的这个想法的想法.
更新2:
如果在编译之后重构Enum,那么它可能不应该给出任何错误,除非它不能应用于枚举(不记得重构是否适用于枚举),但如果它可以应用它将会做起来可能很麻烦,慢一点吧?
更新3:属性包含对它们被分配到的枚举的引用的原因.
实际上,这是一个非常简单的原因,假设以下情况.假设我有一组自定义属性,由于某种原因,我需要在某个时候知道给定属性属于哪个枚举.
而不是编写新代码来确定,为什么不简单地在属性本身中引用给定的枚举?这是对内存消耗的微小折衷,而将来它可以节省运行任何所需过程的宝贵时间,以确定每个属性的给定枚举(甚至只有一个).
Cor*_*rey 10
属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式.
基本上是说DemoEnum.Value1和DemoEnum.Value2不保持常量值.我是对的?
不完全的.
实际问题似乎是使用Enum.虽然它主要用作概念类层次结构的基类,但它似乎是用一些技巧来处理的.对于所有意图和目的,它是一个运行时伪类而不是真正的类.
属性在编译时处理.没有在运行时使用属性装饰对象的机制.因此,引入一些运行时技巧来处理Enum伪类似乎与Attributes函数的方式不兼容.
试试这个:
public class EnumTest : Attribute
{
public int Value;
public object Obj;
}
public enum DemoEnum
{
[EnumTest(Value = (int)DemoEnum.Value1, Obj = DemoEnum.Value1)]
Value1 = 1,
[EnumTest(Value = (int)DemoEnum.Value2)]
Value2 = 2
}
Run Code Online (Sandbox Code Playgroud)
这编译得很好(VS2010中的.NET 4.0),并且属性属性设置正确.我可以检查Obj属性的属性并获得我期望的数据类型.
<意见>
那说......不太确定这会有多大用处.您必须拥有正在装饰的值的实例,因此将值本身存储在属性中似乎有点多余.
</意见>
编辑:可能的解决方案......
让这个渗透了一下(我在睡着的时候做了一些最好的思考),我已经意识到,由于问题在于实际的参数类型(如本问题的答案所述),我们可以解决一下这个问题拳击
public class EnumTest : Attribute
{
public Enum enum;
public EnumTest(object e)
{
enum = e as Enum;
}
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以从一个对象初始化属性,C#和CLR看起来很舒服.您在使用Enum初始化时失去了固有的类型检查,但我相信它达到了既定目标.
| 归档时间: |
|
| 查看次数: |
5656 次 |
| 最近记录: |