我需要一些属性类中的Guid属性,如下所示:
public class SomeAttribute : Attribute { private Guid foreignIdentificator; public Guid ForeignIdentificator { get { return this.foreignIdentificator; } set { this.foreignIdentificator = value; } } }
但是在属性定义中,我只能使用原始类型,它们是常量(我理解为什么,这让我有意义).解决方法可以将"ForeignIdentificator"定义为字符串,并在运行时创建Guid:
public class SomeAttribute : Attribute { private string foreignIdentificator; public string ForeignIdentificator { get { return this.foreignIdentificator; } set { this.foreignIdentificator = value; } } public Guid ForeignIdentificatorGuid { get { return new Guid( ForeignIdentificator ); } } }
不幸的是,我没有检查类型安全性."ForeignIdentificator"属性可以包含任何字符串值,并且在创建过程中Guid将在运行时抛出异常,而不是在编译时抛出异常.
我知道编译器检查"System.Runtime.InteropServices.GuidAttribute"的字符串值是否为"Guid兼容性".这个检查正是我需要的,但我不知道这个检查是否在编译器中硬编码或者我可以明确定义(以及如何).
你知道某种方式,如何确保"Guid compatibilitybilty"检查属性?或者另一种方式,如何在属性中达到类型安全的Guid定义?谢谢.
我过去遇到了你的确切问题.我们只需要它们将GUID作为字符串传递...... VS GUID生成器工具将它提供给我们的默认方式(*F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4).我们基本上做了你做的.我们在插件架构中使用它,因此我们的客户就是使用该界面的客户.如果你看看微软在需要做同样事情时所做的事情,他们就是这样做的.
这样做并不是一个问题.不是一次,我们是否已将此视为现场问题.
但是,您可能希望将该字符串字段命名为GUID,以免混淆您的使用者.添加一些文档,以防他们不知道需要什么格式.
当我看到这个时,我有同样的反应...但后来我继续前进,因为似乎没有类型安全的解决方案.
属性参数必须是常量。如果我违反了规则,我的C#编译器会给出此错误:
属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式
由于C#中没有GUID文字,因此您必须以另一种格式(例如字符串)对GUID进行编码。但是,您还不完全了解:您可以使属性具有采用所需格式的ctor。这是一个与以下示例具有相同ctor的示例System.Guid
:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] sealed class MyGuidAttribute : Attribute { public Guid Guid { get; private set; } // // Summary: // Initializes a new instance of the System.Guid class using the specified array // of bytes. // // Parameters: // b: // A 16 element byte array containing values with which to initialize the GUID. // // Exceptions: // System.ArgumentNullException: // b is null. // // System.ArgumentException: // b is not 16 bytes long. public MyGuidAttribute(byte[] b) { this.Guid = new Guid(b); } // // Summary: // Initializes a new instance of the System.Guid class using the value represented // by the specified string. // // Parameters: // g: // A System.String that contains a GUID in one of the following formats ('d' // represents a hexadecimal digit whose case is ignored): 32 contiguous digits: // dddddddddddddddddddddddddddddddd -or- Groups of 8, 4, 4, 4, and 12 digits // with hyphens between the groups. The entire GUID can optionally be enclosed // in matching braces or parentheses: dddddddd-dddd-dddd-dddd-dddddddddddd -or- // {dddddddd-dddd-dddd-dddd-dddddddddddd} -or- (dddddddd-dddd-dddd-dddd-dddddddddddd) // -or- Groups of 8, 4, and 4 digits, and a subset of eight groups of 2 digits, // with each group prefixed by "0x" or "0X", and separated by commas. The entire // GUID, as well as the subset, is enclosed in matching braces: {0xdddddddd, // 0xdddd, 0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} All braces, commas, // and "0x" prefixes are required. All embedded spaces are ignored. All leading // zeroes in a group are ignored. The digits shown in a group are the maximum // number of meaningful digits that can appear in that group. You can specify // from 1 to the number of digits shown for a group. The specified digits are // assumed to be the low order digits of the group. // // Exceptions: // System.ArgumentNullException: // g is null. // // System.FormatException: // The format of g is invalid. // // System.OverflowException: // The format of g is invalid. public MyGuidAttribute(string g) { this.Guid = new Guid(g); } // // Summary: // Initializes a new instance of the System.Guid class using the specified integers // and byte array. // // Parameters: // a: // The first 4 bytes of the GUID. // // b: // The next 2 bytes of the GUID. // // c: // The next 2 bytes of the GUID. // // d: // The remaining 8 bytes of the GUID. // // Exceptions: // System.ArgumentNullException: // d is null. // // System.ArgumentException: // d is not 8 bytes long. public MyGuidAttribute(int a, short b, short c, byte[] d) { this.Guid = new Guid(a, b, c, d); } // // Summary: // Initializes a new instance of the System.Guid class using the specified integers // and bytes. // // Parameters: // a: // The first 4 bytes of the GUID. // // b: // The next 2 bytes of the GUID. // // c: // The next 2 bytes of the GUID. // // d: // The next byte of the GUID. // // e: // The next byte of the GUID. // // f: // The next byte of the GUID. // // g: // The next byte of the GUID. // // h: // The next byte of the GUID. // // i: // The next byte of the GUID. // // j: // The next byte of the GUID. // // k: // The next byte of the GUID. public MyGuidAttribute(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { this.Guid = new Guid(a, b, c, d, e, f, g, h, i, j, k); } // // Summary: // Initializes a new instance of the System.Guid class using the specified unsigned // integers and bytes. // // Parameters: // a: // The first 4 bytes of the GUID. // // b: // The next 2 bytes of the GUID. // // c: // The next 2 bytes of the GUID. // // d: // The next byte of the GUID. // // e: // The next byte of the GUID. // // f: // The next byte of the GUID. // // g: // The next byte of the GUID. // // h: // The next byte of the GUID. // // i: // The next byte of the GUID. // // j: // The next byte of the GUID. // // k: // The next byte of the GUID. [CLSCompliant(false)] public MyGuidAttribute(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { this.Guid = new Guid(a, b, c, d, e, f, g, h, i, j, k); } }