2008-11-28 674 views
6

necesito una propiedad Guid de alguna clase de atributo de esta manera:¿Cómo tomo un GUID como parámetro de atributo?

public class SomeAttribute : Attribute { 
    private Guid foreignIdentificator; 
    public Guid ForeignIdentificator { 
     get { return this.foreignIdentificator; } 
     set { this.foreignIdentificator = value; } 
    } 
} 

Pero en la definición de atributos que puedo utilizar sólo los tipos primitivos, que son constantes (entiendo por qué, y es que me sentido). La solución puede ser la definición "ForeignIdentificator" como cadena, y la creación de GUID en tiempo de ejecución:

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 me suelto comprobar la seguridad de tipos. La propiedad "ForeignIdentificator" puede contener cualquier valor de cadena y durante la creación de Guid se lanzará una excepción en tiempo de ejecución, no en tiempo de compilación.

Sé que el compilador verifica el valor de la cadena para "System.Runtime.InteropServices.GuidAttribute" para "Guid compatibility". Esta comprobación es exactamente lo que necesito, pero no sé si esta verificación fue codificada en el compilador o si puedo definirla explícitamente (y cómo).

¿Sabe de alguna manera, cómo asegurar la verificación de compatibilidad de Guid para los atributos? O de alguna otra manera, ¿cómo llegar a la definición de Guid tipo segura en atributos? Gracias.

+0

¿Qué es un "identificador"? –

+0

"ForeignIdentificator" es el valor GUID que se define en otro ensamblaje o base de datos o cualquier otra cosa, donde se debe agregar el propietario del atributo. – TcKs

+0

Parece un bushismo. – xr280xr

Respuesta

6

Me he encontrado con su problema exacto en el pasado. Simplemente les pedimos que pasaran el GUID como una cadena ... la forma predeterminada que la herramienta generadora de GUID VS nos la proporciona (* F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4). Básicamente hicimos lo que hiciste. Lo usamos en una arquitectura de plug-in, por lo que nuestros clientes han sido los que usaron la interfaz. Si observa lo que hace Microsoft cuando necesita hacer lo mismo, lo hace.

No ha sido un problema hacerlo de esta manera. No una vez, hemos visto esto como un problema desde el campo.

Es posible que desee nombrar ese GUID de campo de cadena, para no confundir a sus consumidores. Agregue un poco de documentación en caso de que no sepan en qué formato debe estar.

Tuve la misma reacción cuando miré esto ... pero luego seguí adelante, ya que parece que no hay ningún tipo- solución segura

+0

Escribir un nuevo Guid no es un problema para mí (tengo un shourtcut clave para él), pero tengo miedo de otras personas. Pero si no hay manera, cómo asegurar el formato correcto en tiempo de compilación (y me temo que no), debo crear utilidad, que probará todas las definiciones de atributos en el ensamblado compilado. – TcKs

+0

Entiendo su preocupación. Pasamos un tiempo tratando de resolverlo también. En las implementaciones de Microsoft, hacen lo mismo, así que nos damos por vencidos. De nuevo, temimos que sería un problema en el campo, pero no ha surgido una vez como un problema. Solo asegúrate de atrapar la excepción en tu extremo. –

+0

Usted confirma mi conjetura. No buscaré más otra solución. Gracias. – TcKs

4

Los parámetros del atributo deben ser constantes. Si rompo las reglas, mi compilador de C# da este error:

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

Dado que no existen literales GUID en C#, se tiene que codificar el GUID en otro formato, por ejemplo una cadena. Sin embargo, no está completamente en el mar: puede hacer que su atributo tenga un código que tome el formato que desee. Aquí hay un ejemplo con los mismos operadores que 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); 
    } 
} 
+0

Tienes razón. Uso una cuerda para pasar un guid para atribuir también. – IlPADlI

Cuestiones relacionadas