Static fields, inheritance, and Reflection...

 I'm trying to force a class that inherits from a base class that contains a static field to assign a value to this field. I'm not having any luck.

For example, say I have a base class "Shape":

public class Shape

{

public static string Description = "A shape";

}

and I want to create a class that inherits from shape, but I want the new class to be forced to assign a value to 'Description'. Is this possible I know I can't use abstract or virtual along with static..

The reason for this is that I want to be able, when using reflection, to use the FieldInfo class to return the 'Description' of the inheriting class. I know I can assign a value to 'Description' in the constructor of the inheriting class, but the Type.GetFields() method does not return the base class's field.

So another question, how can I get the typeof(MyInheritingClass).GetFields() method to return the static fields of the base class

 

Thanks,

Nasty

 



Answer this question

Static fields, inheritance, and Reflection...

  • Will Riley

    micvos wrote:

    Attributes are used for storing meta data about a class. You can access this information from the type using reflection. Try this code:

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace ConsoleApplication1

    {

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]

    public class DescriptionAttribute : Attribute

    {

    public String Description;

    public DescriptionAttribute(String description)

    {

    Description = description;

    }

    }

    [Description("a value")]

    public class Shape

    {

    }

    [Description("another value")]

    public class ShapeDescendend : Shape

    {

    }

    [Description("a circle")]

    public class Circle: Shape

    {

    }

    class Program

    {

    static void Main(string[] args)

    {

    Console.WriteLine(GetDescription(typeof(Shape)));

    Console.WriteLine(GetDescription(typeof(ShapeDescendend)));

    Console.WriteLine(GetDescription(typeof(Circle)));

    }

    static String GetDescription(Type type)

    {

    object[] attrs = type.GetCustomAttributes(typeof(DescriptionAttribute), true);

    if (attrs.Length == 0)

    return "";

    else

    return ((DescriptionAttribute)attrs[0]).Description;

    }

    }

    }



    Good example, and here's a generic 'AttributeExtractor' that can be used to pull out attributes of any kind. I use it in one of my open source projects.

    // extract attributes of type T in a straightforward, repeatable, non-repetative way.
    // use MemberInfo so we can pass a Type, PropertyInfo, FieldInfo, MethodInfo...etc
    public class AttributeExtractor<T> where T: System.Attribute
    {
    // just get this guy once forever...
    static Type tType = typeof(T);

    //extract the first attribute matching the type T
    public static T ExtractOne(MemberInfo t)
    {
    Attribute[] atts = (Attribute[])t.GetCustomAttributes(tType, true);
    if (atts.Length > 0)
    {
    return atts[0] as T;
    }

    return null;
    }

    //extract all attributes of the type T
    public static T[] ExtractAll(MemberInfo t)
    {
    Attribute[] atts = (Attribute[])t.GetCustomAttributes(tType, true);
    return (T[])atts;
    }


    // get the first one of a type from some attributes you have somehow
    public static T ExtractOne(Attribute[] l)
    {
    foreach (Attribute att in l)
    {
    if (att is T)
    {
    return att as T;
    }
    }

    return null;
    }

    // so you have some attributes and want to filter for a type...
    public static T[] ExtractAll(Attribute[] l)
    {
    List<T> toReturn = new List<T>();
    foreach (Attribute att in l)
    {
    if (att is T)
    {
    toReturn.Add((T)att);
    }
    }

    return toReturn.ToArray();
    }
    }


  • MattGreer88

    Attributes are used for storing meta data about a class. You can access this information from the type using reflection. Try this code:

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace ConsoleApplication1
    {
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
        public class DescriptionAttribute : Attribute
        {
            public String Description;
            public DescriptionAttribute(String description)
            {
                Description = description;
            }
        }

        [Description("a value")]
        public class Shape
        {
        }

        [Description("another value")]
        public class ShapeDescendend : Shape
        {
        }

        [Description("a circle")]
        public class Circle: Shape
        {
        }


        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(GetDescription(typeof(Shape)));
                Console.WriteLine(GetDescription(typeof(ShapeDescendend)));
                Console.WriteLine(GetDescription(typeof(Circle)));
            }

            static String GetDescription(Type type)
            {
                object[] attrs = type.GetCustomAttributes(typeof(DescriptionAttribute), true);
                if (attrs.Length == 0)
                    return "";
                else
                    return ((DescriptionAttribute)attrs[0]).Description;
            }
        }
    }



  • Jeek

    Why not force the providers of the plugin to implement the attribute in the same way as you enforce them to implement the IFormat interface Just don't load the dll if the attribute is not present.

  • jk-olap

    Why not create our own attribute with a Description value

  • Alvin Kuiper

    Micvos, I recently had the same problem that mastynate has. I ended up using the classes names because it wasn't that big a deal (It wasn't for commercial use anyways).

    The solution you suggest, not only it works, but it looks cool too!

    Anyways... I'm going to describe briefly the circunstances that required a static property to be abstract.

    By application need to support plugins through reflection. There was a folder reserved for that purpose were dlls could be saved in and the application would automatically load this dll's as plugins. This dlls had to implement the IFormat interface that was in my domain dll. Anyhow, at some point the user had to be able to select what Format he wished to use, so in a combo box I displayed all Formats supported in my application plus all the formats detected in my plugin folder. And this is were I wanted to fill the combobox using a static Description property without the need of instantiating this classes.
    However, this plugins were supposed to be implemented by a third party, so I needed to force them to implement this static property, but I couldn't do it. The same problem I would have if I am to use an Attribute.

    Is there anyway to do this
    Can you force the derived classes to have the Description Attribute

    Thanks,
    Fernando.


  • Andreas Haug

    Can an attribute of a class be accessed like a static field For instance, the value of SomeClass.SomeStaticField can be accessed without instantiating the class... can the same be said for an Attribute

    Thanks for the suggestion,

    Nasty


  • pkv

    Thanks for the suggestion.. but I'm trying to access the 'Description' field without instantiating the class.
  • Rodrigo Luis dos Santos

    Use polymorphism rather than reflection:

    public class Shape
    {
        public virtual string Description
        {
            get
            {
                return "A Shape";
            }
        }
    }

    public class Rectangle
    {
        public override string Description
        {
            get
            {
                return "Rectangle";
            }
        }
    }

    public class Circle
    {
        public override string Description
        {
            get
            {
                return "Circle";
            }
        }
    }

    Shape a = new Circle();
    Shape b = new Rectangle();

    Console.WriteLine(a.Description); // writes "Circle"
    Console.WriteLine(b.Description); // writes "Rectangle"


     


  • Static fields, inheritance, and Reflection...