Atributos más útiles [cerrado]

784

Sé que los atributos son extremadamente útiles. Hay algunos predefinidos, como el [Browsable(false)]que le permite ocultar propiedades en la pestaña de propiedades. Aquí hay una buena pregunta que explica los atributos: ¿Qué son los atributos en .NET?

¿Cuáles son los atributos predefinidos (y su espacio de nombres) que realmente usa en sus proyectos?

wusher
fuente
27
¿Que pregunta? , toda la página está repleta de hermosas respuestas con maravillosas explicaciones. Mientras leo esto, obtuve experiencia como entrevistar a muchos expertos sobre su punto de vista. +100 por la pregunta.
Muthu Ganapathy Nathan
Estoy de acuerdo, preguntas como esta son algunas de las más valiosas: hacen que SO sea menos útil que se cierre.
David Thielen

Respuestas:

669

[DebuggerDisplay]puede ser realmente útil ver rápidamente la salida personalizada de un Tipo cuando pasa el mouse sobre la instancia del Tipo durante la depuración. ejemplo:

[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
    public string FirstName;
    public string LastName;
}

Así es como debería verse en el depurador:

texto alternativo

Además, vale la pena mencionar que el [WebMethod]atributo con el CacheDurationconjunto de propiedades puede evitar la ejecución innecesaria del método del servicio web.

Vivek
fuente
62
Wow, eso es realmente bueno saberlo. Por lo general, he logrado lo mismo al anular ToString, pero esto es mejor.
Brian
17
Tenga cuidado con esto, muerde una porción mucho más grande de su CPU que ToString.
Nikola Radosavljević
1
También puede usar esto para mostrar el resultado de los métodos. Esto puede generar una experiencia de depuración bastante confusa si el método (o get-property) tiene efectos secundarios.
Øyvind Skaar
44
@ NikolaRadosavljević solo ocuparía la potencia de la CPU durante la depuración
Nickolay Kondratyev
2
@Nickolay Kondratyev: no conozco todos los entresijos, pero puede consultar las siguientes prácticas recomendadas de servicios web que pueden llevarlo a algunas conclusiones: blogs.msdn.com/b/jaredpar/archive/2011/03/ 18 / ...
Nikola Radosavljević
273

System.ObsoleteEs uno de los atributos más útiles en el marco, en mi opinión. La capacidad de generar una advertencia sobre el código que ya no debería usarse es muy útil. Me encanta tener una manera de decirles a los desarrolladores que algo ya no debería usarse, así como tener una manera de explicar por qué y señalar la mejor / nueva forma de hacer algo.

El también Conditional attributees bastante útil para el uso de depuración. Le permite agregar métodos en su código para propósitos de depuración que no se compilarán cuando cree su solución para su lanzamiento.

Luego hay muchos atributos específicos de los controles web que encuentro útiles, pero son más específicos y no tienen ningún uso fuera del desarrollo de los controles del servidor de lo que he encontrado.

Dan Herbert
fuente
50
Puede pasar "verdadero" como uno de los parámetros a System.Obsolete, lo que hace que la advertencia se convierta en un error y, por lo tanto, rompa la compilación. Obviamente, esto debe hacerse una vez que haya limpiado todas las advertencias. :)
Adrian Clark
14
Una vez que limpie todas las advertencias, ¿no sería mejor simplemente eliminar el método?
Pedro
10
@Pedro: a veces no puedes por razones de compatibilidad con versiones anteriores. Si es privado y no se usa, sí, elimínelo.
Fantius
3
@plinth Lanzar una excepción sería una mala idea por muchas razones, ya que la razón principal para usar Obsolete () es que puedes mantener el código compilado funcionando mientras estás en una fase de transición. Si no está permitiendo que nadie llame al método, ¿por qué no simplemente eliminarlo?
Dan Herbert, el
17
@plinth Es para evitar que el nuevo código use el método. El código antiguo seguirá siendo compatible con binarios si un método se marca como obsoleto, pero dejará de funcionar si arroja una excepción. Si alguien está utilizando la reflexión de conseguir alrededor de la bandera "Obsolte", entonces usted tiene problemas peores ...
Dan Herbert
204

[Flags]Es bastante útil. Azúcar sintáctico, sin duda, pero aún bastante agradable.

[Flags] 
enum SandwichStuff
{
   Cheese = 1,
   Pickles = 2,
   Chips = 4,
   Ham = 8,
   Eggs = 16,
   PeanutButter = 32,
   Jam = 64
};

public Sandwich MakeSandwich(SandwichStuff stuff)
{
   Console.WriteLine(stuff.ToString());
   // ...
}

// ...

MakeSandwich(SandwichStuff.Cheese 
   | SandwichStuff.Ham 
   | SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"

Leppie señala algo que no me había dado cuenta, y que más bien amortigua mi entusiasmo por este atributo: no le indica al compilador que permita combinaciones de bits como valores válidos para las variables de enumeración, el compilador permite esto para las enumeraciones independientemente. Mi fondo C ++ se muestra a través de ... suspiro

Shog9
fuente
Entonces, ¿qué hace exactamente el atributo Banderas?
Andrei Rînea
13
Espero que se den cuenta que el atributo Flags molesta a todos. No es necesario / usado en absoluto, excepto el TypeConverter.
leppie
3
@leppie: ToString () también. Pero ... wow Por alguna razón, esperaba que el comportamiento de las enumeraciones sin el atributo fuera el mismo que C ++: los valores producidos producen un número entero (no se puede pasar como está al método esperando enum param). Ahora veo que ese no es el caso. Débil ... ok, las enumeraciones .NET apestan.
Shog9
2
[Banderas] realmente solo ayuda al depurador y a las funciones .ToString () a saber que un valor es potencialmente una combinación de varias declaraciones en la enumeración. No estoy seguro, podría hacer que Intellisense lo ayude a usar la enumeración de manera más efectiva también.
Kenzi
31
[Flags]tiene un uso mayor que ser simplemente azúcar sintáctica. Al usar los servicios web, la serialización / deserialización no funcionará si SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamse pasa un valor como . Sin el [Flags]atributo, el deserializador no sabrá que el valor puede ser una combinación de banderas. Aprendí esto de la manera difícil después de pasar unos dos días pensando por qué mi WCF no estaba funcionando.
Anchit
177

Me gusta [DebuggerStepThrough]de System.Diagnostics .

Es muy útil para evitar entrar en esos métodos o propiedades de una línea de no hacer nada (si se ve obligado a trabajar en una .Net temprana sin propiedades automáticas). Ponga el atributo en un método corto o en el captador o definidor de una propiedad, y volará directamente incluso al presionar "entrar en" en el depurador.

Blair Conrad
fuente
55
Muchas veces desearía saber sobre esta propiedad
wusher
1
Es una pena que se haya roto con los cierres; consulte gregbeech.com/blogs/tech/archive/2008/10/17/… para obtener más información.
Greg Beech
3
También es útil para cualquier código WM_Paint que sepa que funciona :)
Pondidum
@GregBeech Esa URL devuelve un error .NET. ¡De buen tono! :)
smdrager
@smdrager: debe haber sido un problema temporal, hoy parece funcionar para mí.
Greg Beech
135

Para lo que vale, aquí hay una lista de todos los atributos .NET . Hay varios cientos.

¡No conozco a nadie más, pero tengo algunos RTFM serios que hacer!

wprl
fuente
33
Lista desplazado tiene como .NET 1.1 aquí está la lista de 3,5 msdn.microsoft.com/en-us/library/system.attribute.aspx (Usted tiene que desplazarse un poco)
kay.one
2
Se actualizó el enlace en la pregunta. Ahora es la lista completa para 3.5
R. Martinho Fernandes
8
En realidad, eso enlaza con lo último, no 3.5 específicamente.
Brian Ortiz
1
Ahora, si solo la lista no fuera solo una lista de enlaces, sino el nombre y la descripción. Oh bien. @BrianOrtiz tiene razón. La lista está en la versión 4.5.
Luminoso
Simplemente cambie el marco al que apunta en la parte superior donde dice "Otras versiones".
Novaterata
129

Mi voto sería por Conditional

[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
    // your code here
}

Puede usar esto para agregar una función con funciones avanzadas de depuración; por ejemplo Debug.Write, solo se llama en compilaciones de depuración y, por lo tanto, le permite encapsular la lógica de depuración compleja fuera del flujo principal de su programa.

Steve Cooper
fuente
55
¿No es lo mismo que hacer #if DEBUG?
Neil N
10
De alguna manera, #if DEBUG significa que la persona que llama tampoco tiene que llamarlo, mientras que el Conditioinal deja la llamada pero lo convierte en un NOP que se elimina en JIT.
Rangoric
23
Además, normalmente usaría #if DEBUG alrededor de las llamadas y [Condicional] alrededor de los métodos . Entonces, si llama a un método de depuración 100 veces, desactivarlo es cuestión de un solo cambio de código, no 100.
Steve Cooper
13
El comentario de Rangoric es sutilmente incorrecto (al menos para C #): el método se incluye sin modificaciones; el sitio de la llamada en sí se omite. Esto tiene algunas implicaciones: los parámetros no se evalúan y el método condicional está contenido, sin modificaciones, en la salida del compilador. Puedes verificar esto con reflexión. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/…
Mark Sowul
97

Yo siempre uso el DisplayName, Descriptiony DefaultValueatributos sobre propiedades públicas de mis controles de usuario, controles personalizados o cualquier clase Voy a editar a través de una rejilla de propiedades. Estas etiquetas son utilizadas por .NET PropertyGrid para formatear el nombre, el panel de descripción y los valores en negrita que no están establecidos en los valores predeterminados.

[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
    ...
} 

Solo deseo que IntelliSense de Visual Studio tenga Descriptionen cuenta el atributo si no se encuentra ningún comentario XML. Evitaría tener que repetir la misma oración dos veces.

Anthony Brien
fuente
3
No puedo creer que nadie te haya señalado Descriptionhasta que ... Es de lo más útil para mí cuando se usa con enumeraciones ...
nawfal
68

[Serializable]se usa todo el tiempo para serializar y deserializar objetos hacia y desde fuentes de datos externas como xml o desde un servidor remoto. Más sobre esto aquí.

Gilligan
fuente
En realidad, se refiere a un atributo psuedo, ya que C # emite un indicador de metadatos para [Serializable], no una instancia de atributo personalizado;)
TraumaPony
1
Si bien es muy útil [Serializable] está lejos de ser perfecto. Requiere demasiados retoques y pruebas y errores para obtener el resultado que desea.
shoosh
¡Secundaré ese shoosh!
John Bubriski
System.NonSerializedAttribute es útil si desea más control sobre la serialización automática.
CSharper
Como nota al margen, agregaría que el rendimiento de la serialización .Net incorporada es bastante pobre, como 2 o 3 órdenes de magnitud más lento que el código hecho a mano.
redcalx
57

En el espíritu de Hofstadt, el [Attribute]atributo es muy útil, ya que es cómo se crean sus propios atributos. He usado atributos en lugar de interfaces para implementar sistemas de complementos, agregar descripciones a Enums, simular despachos múltiples y otros trucos.

C. Lawrence Wenham
fuente
13
¡Suena bien! ¿Le importaría mostrar algunos ejemplos del sistema de complementos y las descripciones de enumeración? Esas son las dos cosas que me interesa implementar.
John Bubriski
46

Aquí está la publicación sobre el atributo interesante InternalsVisibleTo . Básicamente lo que hace imita la funcionalidad de acceso de amigos C ++. Es muy útil para pruebas unitarias.

xrost
fuente
77
¿No quiere decir útil para hackear una prueba unitaria en algo que no pudo / no debe probarse?
the_drow
@the_drow: Hablas de 'accesores privados': msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx
habakuk
@habakuk: En realidad no. Hay casos en los que las clases internas deben exponerse para pruebas unitarias, generalmente debido a un mal diseño.
the_drow
2
@the_drow: No diría que InternalsVisibleTo es malo para las pruebas unitarias; puede crear y probar "unidades" más pequeñas que no son visibles fuera de su proyecto (le ayuda a tener una API limpia y pequeña). Pero si necesita 'accesores privados' para probar algo en la unidad, probablemente haya algo mal.
habakuk
10
@the_drow No estoy de acuerdo con tu afirmación que internalno es pública. Es público dentro del ensamblaje que se está probando y debe probarse de forma unitaria para que otras clases dentro del ensamblaje puedan asumir su funcionalidad de corrección. Si no lo prueba unitariamente, deberá probar sus funciones en todas las clases consumidoras.
tvanfosson
28

Sugeriría [TestFixture]y [Test]- de la biblioteca nUnit .

Las pruebas unitarias en su código brindan seguridad en la refactorización y la documentación codificada.

Adrian Wible
fuente
26
[XmlIgnore]

ya que esto le permite ignorar (en cualquier serialización xml) los objetos 'primarios' que de otro modo causarían excepciones al guardar.

jimi
fuente
25

No está bien nombrado, no está bien soportado en el marco y no debería requerir un parámetro, pero este atributo es un marcador útil para clases inmutables:

[ImmutableObject(true)]
Neil Whitaker
fuente
66
Según los documentos, solo se usa en tiempo de diseño (desafortunadamente).
Hans Ke sting
1
Dado que esto es solo en tiempo de diseño, tal vez sería mejor crear su propia ImmutableObjectAttributeclase, al menos podría eliminar el parámetro.
Roy Tinker
25

Me gusta usar el [ThreadStatic]atributo en combinación con programación basada en hilos y en pila. Por ejemplo, si quiero un valor que quiero compartir con el resto de una secuencia de llamadas, pero quiero hacerlo fuera de banda (es decir, fuera de los parámetros de la llamada), podría emplear algo como esto.

class MyContextInformation : IDisposable {
    [ThreadStatic] private static MyContextInformation current;

    public static MyContextInformation Current {
        get { return current; }
    }

    private MyContextInformation previous;


    public MyContextInformation(Object myData) {
       this.myData = myData;
       previous = current;
       current = this;
    }

    public void Dispose() {
       current = previous;
    }
}

Más adelante en mi código, puedo usar esto para proporcionar información contextual fuera de banda a las personas aguas abajo de mi código. Ejemplo:

using(new MyContextInformation(someInfoInContext)) {
   ...
}

El atributo ThreadStatic me permite abarcar la llamada solo al hilo en cuestión, evitando el problema desordenado del acceso a datos a través de los hilos.

Ajaxx
fuente
y como acceder entonces? No entiendo el punto de su muestra de uso aquí. ¿Puedes explicar?
Beachwalker
@Beachwalker Current debe ser estático, edítelo ahora. Ahora puede acceder MyContextInformation.Currentpara obtener el contexto activo en la pila. Esto es algo que es un muy buen concepto en ciertos casos, nuestro motor (mi compañía) lo usa para muchos propósitos.
Felix K.
23

El DebuggerHiddenAttribute que permite evitar ingresar al código que no debe ser depurado.

public static class CustomDebug
{
    [DebuggerHidden]
    public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}

...

// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception()); 

También evita mostrar métodos en el seguimiento de la pila, útil cuando se tiene un método que simplemente envuelve otro método:

[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
    return GetElementAt(position.X, position.Y);
}

public Element GetElementAt(Single x, Single y) { ... }

Si ahora llama GetElementAt(new Vector2(10, 10))y se produce un error en el método envuelto, la pila de llamadas no muestra el método que está llamando al método que arroja el error.

Felix K.
fuente
21

DesignerSerializationVisibilityAttributees muy útil. Cuando coloca una propiedad de tiempo de ejecución en un control o componente, y no desea que el diseñador la serialice, la usa así:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
configurador
fuente
44
Muy útil para los componentes WinForms. usar junto con [Browsable (false)]
Mark Heath el
3
Buen punto: [Browsable(false)]es necesario ocultarlo del usuario del diseñador, donde [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]es necesario para que no se serialice.
Configurador
17

Solo unos pocos atributos obtienen soporte del compilador, pero un uso muy interesante de los atributos está en AOP: PostSharp usa sus atributos a medida para inyectar IL en los métodos, permitiendo todo tipo de habilidades ... log / trace son ejemplos triviales, pero algunos otros buenos ejemplos son cosas como la implementación automática INotifyPropertyChanged ( aquí ).

Algunos que ocurren e impactan el compilador o el tiempo de ejecución directamente :

  • [Conditional("FOO")] - las llamadas a este método (incluida la evaluación de argumentos) solo se producen si el símbolo "FOO" se define durante la compilación
  • [MethodImpl(...)] - se usa para indicar algunas cosas como sincronización, alineación
  • [PrincipalPermission(...)] - se usa para inyectar controles de seguridad en el código automáticamente
  • [TypeForwardedTo(...)]- Se usa para mover tipos entre ensamblajes sin reconstruir los llamadores

Para las cosas que se verifican manualmente a través de la reflexión, soy un gran admirador de los System.ComponentModelatributos; cosas como [TypeDescriptionProvider(...)], [TypeConverter(...)]y [Editor(...)]que pueden cambiar completamente el comportamiento de los tipos en escenarios de enlace de datos (es decir, propiedades dinámicas, etc.).

Marc Gravell
fuente
15

Si tuviera que hacer un rastreo de cobertura de código, creo que estos dos serían los mejores:

 [Serializable]
 [WebMethod]
FlySwat
fuente
15
[WebMethod] se usa para decorar un método que está expuesto en un servicio web. [Serializable] marca sus objetos para que puedan ser serializados para propósitos tales como pasarlos a través de dominios de aplicaciones.
Kev
15

He estado usando el [DataObjectMethod]últimamente. Describe el método para que pueda usar su clase con ObjectDataSource (u otros controles).

[DataObjectMethod(DataObjectMethodType.Select)] 
[DataObjectMethod(DataObjectMethodType.Delete)] 
[DataObjectMethod(DataObjectMethodType.Update)] 
[DataObjectMethod(DataObjectMethodType.Insert)] 

Más información

wusher
fuente
12

En nuestro proyecto actual, usamos

[ComVisible(false)]

Controla la accesibilidad de un miembro o tipo administrado individual, o de todos los tipos dentro de un ensamblado, a COM.

Más información

Ahmed
fuente
12
[TypeConverter(typeof(ExpandableObjectConverter))]

Le dice al diseñador que expanda las propiedades que son clases (de su control)

[Obfuscation]

Indica a las herramientas de ofuscación que tomen las acciones especificadas para un ensamblaje, tipo o miembro. (Aunque normalmente utiliza un nivel de ensamblaje[assembly:ObfuscateAssemblyAttribute(true)]

Chris S
fuente
1
Supuse, pero estaba equivocado. El atributo de Ofuscación es solo una pista para los obfsucadores de terceros. No hace que el compilador ofusque nada por defecto.
Dan Is Fiddling By Firelight
@DanNeely gratis para usuarios de Visual Studio Pro / Ultimate!
Chris S
44
Si se refiere a DotFuscator Community Edition, el nivel de protección que brinda es tan bajo que, en el mejor de los casos, apenas cuenta para nada.
Dan Is Fiddling By Firelight
@ricovox He agregado un resumen
Chris S
9

Los atributos que más uso son los relacionados con la serialización XML.

XmlRoot

XmlElement

XmlAttribute

etc ...

Extremadamente útil cuando se realiza un análisis o serialización XML rápida y sucia.

Brannon
fuente
8

Siendo un desarrollador de nivel medio me gusta

System.ComponentModel.EditorBrowsableAttribute Me permite ocultar propiedades para que el desarrollador de la interfaz de usuario no se vea abrumado por las propiedades que no necesitan ver.

System.ComponentModel.BindableAttributeAlgunas cosas no necesitan estar vinculadas a datos. Nuevamente, disminuye el trabajo que los desarrolladores de UI deben hacer.

También me gusta el DefaultValueque mencionó Lawrence Johnston.

System.ComponentModel.BrowsableAttributey Flagsse usan regularmente.

Yo uso System.STAThreadAttribute System.ThreadStaticAttribute cuando sea necesario.

Por cierto. I estos son tan valiosos para todos los desarrolladores de .Net framework.

ElGringoGrande
fuente
8

[EditorBrowsable(EditorBrowsableState.Never)]le permite ocultar propiedades y métodos de IntelliSense si el proyecto no está en su solución. Muy útil para ocultar flujos no válidos para interfaces fluidas. ¿Con qué frecuencia desea obtener GetHashCode () o Equals ()?

Para MVC le [ActionName("Name")]permite tener una acción Obtener y Publicar acción con la misma firma de método, o usar guiones en el nombre de la acción, que de otra manera no sería posible sin crear una ruta para ello.

smdrager
fuente
8

Considero que es importante mencionar aquí que los siguientes atributos también son muy importantes:

STAThreadAttribute 

Indica que el modelo de subprocesamiento COM para una aplicación es un apartamento de subproceso único (STA).

Por ejemplo, este atributo se usa en aplicaciones de formularios Windows Forms:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Y también ...

SuppressMessageAttribute

Suprime el informe de una violación específica de la regla de la herramienta de análisis estático, lo que permite múltiples supresiones en un solo artefacto de código.

Por ejemplo:

[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
    string fileIdentifier = name;
    string fileName = name;
    string version = String.Empty;
}
Eric Javier Hernandez Saura
fuente
¿Se utiliza STAThread para evitar que su aplicación genere accidentalmente otra instancia de sí misma al inicio?
Luminoso
7

Fuera de mi cabeza, aquí hay una lista rápida, más o menos ordenada por frecuencia de uso, de los atributos predefinidos que realmente uso en un gran proyecto (~ 500k LoC):

Flags, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.

Enigma de Eldritch
fuente
2
+1 para ThreadStatic, sorprendido de que nadie lo haya mencionado hasta ahora, y también para el enfoque estadístico
staafl
6

Genero clase de entidad de datos a través de CodeSmith y uso atributos para alguna rutina de validación. Aquí hay un ejemplo:

/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
    get { return _firmGUID; }
    set { _firmGUID = value; }
}

Y obtuve una clase de utilidad para hacer la validación basada en los atributos adjuntos a la clase de entidad de datos. Aquí está el código:

namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
    /// <summary>
    /// Data entity validation
    /// </summary>
    /// <param name="data">Data entity object</param>
    /// <returns>return true if the object is valid, otherwise return false</returns>
    public static bool Validate(object data)
    {
        bool result = true;
        PropertyInfo[] properties = data.GetType().GetProperties();
        foreach (PropertyInfo p in properties)
        {
            //Length validatioin
            Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
            if (attribute != null)
            {
                ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
                if (validLengthAttribute != null)
                {
                    int maxLength = validLengthAttribute.MaxLength;
                    int minLength = validLengthAttribute.MinLength;
                    string stringValue = p.GetValue(data, null).ToString();
                    if (stringValue.Length < minLength || stringValue.Length > maxLength)
                    {
                        return false;
                    }
                }
            }
            //Range validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
            if (attribute != null)
            {
                ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
                if (validRangeAttribute != null)
                {
                    decimal maxValue = decimal.MaxValue;
                    decimal minValue = decimal.MinValue;
                    decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
                    decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
                    decimal decimalValue = 0;
                    decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
                    if (decimalValue < minValue || decimalValue > maxValue)
                    {
                        return false;
                    }
                }
            }
            //Regex validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
            if (attribute != null)
            {
                ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
                if (validRegExAttribute != null)
                {
                    string objectStringValue = p.GetValue(data, null).ToString();
                    string regExString = validRegExAttribute.RegExString;
                    Regex regEx = new Regex(regExString);
                    if (regEx.Match(objectStringValue) == null)
                    {
                        return false;
                    }
                }
            }
            //Required field validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
            if (attribute != null)
            {
                ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
                if (validRequiredAttribute != null)
                {
                    object requiredPropertyValue = p.GetValue(data, null);
                    if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
                    {
                        return false;
                    }
                }
            }
        }
        return result;
    }
}
}
Ming Yeh
fuente
5

[System.Security.Permissions.PermissionSetAttribute] permite que las acciones de seguridad para un PermissionSet se apliquen al código mediante la seguridad declarativa.

// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public FullConditionUITypeEditor() { }
}
CSharper
fuente