Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding additional attributes to each property of a class

Say I have a class with any number of properties of any type

public class Test
{
public string A {get;set;}
public object B {get;set;}
public int C {get;set;}
public CustomClass D {get;set;}
}

I want all of the objects inside this class to have a notion of 'errors' and 'warnings'. For example, based on some condition in another class, I might want to set a warning on property A, and then display that information in the GUI. The GUI is not my concern; rather how should I set this warning? I would love to be able to do something like:

For every property in a class, add a 'Warning' and 'Error' property such that I can do..

Test t = new Test();
t.A.Warning = "This is a warning that the GUI will know to display in yellow".
t.B.Error = null;

What is the best way to go about doing this? It would be nice if I could add a custom attribute to each property of the class that would add these additional properties and allow me to access them in a clear way.

I have seen solutions that add a Dictionary to the parent class (Test), and then pass in strings that match the property names, or use reflection to get the property name and pass that in, but I would prefer something cleaner.

like image 826
user981225 Avatar asked Nov 30 '11 19:11

user981225


People also ask

How do I add custom attributes to my framework?

AttributeUsage has a named parameter, AllowMultiple , with which you can make a custom attribute single-use or multiuse. In the following code example, a multiuse attribute is created. In the following code example, multiple attributes of the same type are applied to a class. [Author("P.

What are attributes in properties?

An attribute is a quality or character ascribed to or considered to belong to, or be inherent in, a person or thing. A property is a quality or characteristic belonging to a person or thing, with its original use implying ownership, and also either being essential or special.

What are attributes used for in C#?

An attribute is a declarative tag that is used to convey information to runtime about the behaviors of various elements like classes, methods, structures, enumerators, assemblies etc. in your program. You can add declarative information to a program by using an attribute.


3 Answers

You could add a custom attribute that you want to the property and then use an extension method on object to access those attributes.

Something like this should work

First you will need to create your attribute class

[AttributeUsage(AttributeTargets.All/*, AllowMultiple = true*/)]
public class WarningAttribute : System.attribute
{
   public readonly string Warning;

   public WarningAttribute(string warning)
   {
      this.Warning = warning;
   }    
}

More Reading Here

Use it as such

[WarningAttribute("Warning String")]
public string A {get;set;}

Then access it as so MSDN Article

public static string Warning(this Object object) 
{
    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(object);

    foreach (System.Attribute attr in attrs)
        {
            if (attr is WarningAttrbiute)
            {
                return (WarningAttribute)attr.Warning;
            }
        } 
}

Then if you have an item that you want to access the warning on you can simply call

test.A.Warning;

If you're wanting to set the warning string you could implement some kind of setter for that a little more cleanly. Potentially through setting a secondary object or property type.


An alternative method to do this would be instead of just using string and object you could create a custom generic type to handle that property setting.

Something like

public class ValidationType<T>
{
   public T Value {get; set;}
   public string Warning {get; set;}
   public string Error {get; set;}

   public ValidationType(T value)
   {
      Value = value;
   }
}

Use like

var newWarning = new ValidationType<string>("Test Type");
newWarning.Warning = "Test STring";
Console.WriteLine("newWarning.Value");

like image 79
msarchet Avatar answered Oct 23 '22 15:10

msarchet


If you could get away with a method instead of property, than you could create an extension for object - but then it would be hard to narrow it's use just for some classes.

Something like:

public static void Warning(this object target, string message)
{
...
}

public static String GetWarning(this object target)
{
}

Of course it would be hard to maintain such a warning in the object's state, but then you could use some dictionaries, etc.

like image 38
Piotr Zierhoffer Avatar answered Oct 23 '22 14:10

Piotr Zierhoffer


Rather than trying to attribute the properties, I would suggest adding a collection of error/warning properties to a base class that your business objects inherit from.

This way, you can provide more detailed information, you can remove them when they have been displayed to the user, and, if you are sending your data out over "the wire" (web services, wcf services), the errors can travel with your objects instead of requiring special processing to send the attributes.

like image 2
competent_tech Avatar answered Oct 23 '22 14:10

competent_tech