2008-11-28 3 views
6

мне нужно свойство Guid в каком-нибудь классе атрибута, как это:Как использовать 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); } 
    } 
} 

Unahppily я освобождаю проверить безопасность типов. Свойство ForeignIdentificator может содержать любое строковое значение, и во время создания Guid будет исключать исключение во время выполнения, а не во время компиляции.

Я знаю, что компилятор проверяет строковое значение для «System.Runtime.InteropServices.GuidAttribute» для «Guid compatible». Эта проверка именно то, что мне нужно, но я не знаю, была ли эта проверка i жестко закодирована в компиляторе или я могу явно определить (и как).

Знаете ли вы, как защитить «Guid compatibilty» проверку атрибутов? Или каким-то другим способом, как достичь типа безопасного определения Guid в атрибутах? Спасибо.

+0

Что такое «Идентификатор»? – 2008-11-28 13:31:03

+0

«ForeignIdentificator» - это значение GUID, которое определено в другой сборке или базе данных или что-то еще, где должен быть добавлен владелец атрибута. – TcKs 2008-11-28 13:33:14

+0

Это звучит как бушизм. – xr280xr 2018-01-26 19:48:24

ответ

6

Я столкнулся с вашей конкретной проблемой в прошлом. Мы просто потребовали, чтобы они передавали GUID в виде строки ... по умолчанию, которую дает нам инструмент генератора VS GUID (* F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4). Мы по существу сделали то, что вы сделали. Мы используем его в плагиновую архитектуру, поэтому наши клиенты используют интерфейс. Если вы посмотрите на то, что делает Microsoft, когда им нужно сделать то же самое, они это делают.

Это не было проблемой для этого. Не однажды мы видели это как проблему с поля.

Возможно, вы захотите назвать этот идентификатор GUID строки, чтобы не путать ваших потребителей. Добавьте некоторую документацию, если они не знают, в каком формате она должна быть.

У меня была такая же реакция, когда я смотрел на это ... но потом я просто перешел, поскольку, похоже, безопасное решение.

4

Параметры атрибута должны быть постоянными. Если я нарушу правило, мой C# компилятор выдаст сообщение об ошибке:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Поскольку нет GUID литералов в C#, вы должны кодировать в GUID в другом формате, например, строка. Однако вы не полностью в море: вы можете сделать свой атрибут ctor, который принимает желаемый формат. Вот пример с теми же ctors, что и 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); 
    } 
}