CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Using reflection to retrieve the default field value

    Hello,
    Using reflection, I'm trying to retrieve the default value for a field. In the code below, I would like to retrieve the value of 10. I can retrieve the name
    of the field, its type and other meta-data, but I can't seem to retrieve the default value.

    How do I do this?

    Thanks,

    Arjay


    Code:
    // Sample code from the internet
    using System;
    using System.Reflection;
     
    class MyClass
    {
    publicint MyPublicInstanceField;
    privateconstint MyPrivateConstField = 10;
    }
    
    class FieldAttributesExample
    {
    publicstaticvoid Main()
    {
    	 Type t = (typeof(MyClass));
    	 string str;
    	 FieldInfo[] fiAry = t.GetFields( BindingFlags.Static |
    	 BindingFlags.Instance | BindingFlags.Public |
    	 BindingFlags.NonPublic | BindingFlags.DeclaredOnly );
     
    	 foreach (FieldInfo fi in fiAry)
    	 {
    		 Console.WriteLine("Field {0} is: ", fi.Name);
    		 str = ((fi.Attributes & FieldAttributes.Static) != 0) ?
    		 "Static" : "Instance";
    		 Console.Write(str + " ");
    		 str = ((fi.Attributes & FieldAttributes.Public) != 0) ?
    		 "Public" : "Non-Public";
    		 Console.Write(str + " ");
    		 str = ((fi.Attributes & FieldAttributes.Literal) != 0) ?
    		 "Literal" : String.Empty;
    		 Console.WriteLine(str);
    	 }
    }
    }
    
    The output is:
    Code:
    Field MyPublicInstanceField is:
    Instance Public
    Field MyPrivateConstField is:
    Static Non-Public

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using reflection to retrieve the default field value

    Anyone, please?

  3. #3
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Using reflection to retrieve the default field value

    What do you mean by 'default value' ?

    Do you mean the value which the constructor of the class initially assigns to this field ?

    To do this you can either

    (a) write a custom attribute and attach it to the field which reflection can then pick up

    (b) create an instance of the class (assuming its constructor has no arguments) and then retrieve the value of the field using a similar reflection technique as to what you're doing.

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using reflection to retrieve the default field value

    Quote Originally Posted by darwen
    What do you mean by 'default value' ?
    Thanks for answering. By 'default value', I mean the value initialized when the field (variable) is declared.

    In the include sample code, for the line:

    private const int MyPrivateConstField = 10;

    The default value would be 10.

    The 10 is what I'm looking for (or whatever value it happens to be).

  5. #5
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Using reflection to retrieve the default field value

    The above still applies : (a) or (b).

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  6. #6
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Using reflection to retrieve the default field value

    Okay, I'm feeling generous. Try this :

    Code:
    public class TestClass
    {
    	private int m_nValue = 100;
    
    	public TestClass()
    	{
    	}
    }
    
    // code
    Type t = typeof(TestClass);
    ConstructorInfo infoConstructor = t.GetConstructor(Type.EmptyTypes);
    TestClass testClass = infoConstructor.Invoke(new object[0] { }) as TestClass;
    
    FieldInfo[] aFieldInfo = t.GetFields( BindingFlags.Static |
    			BindingFlags.Instance | BindingFlags.Public |
    			BindingFlags.NonPublic | BindingFlags.DeclaredOnly );
    
    foreach (FieldInfo infoField in aFieldInfo)
    {
    	object objField = infoField.GetValue(testClass);
    	System.Diagnostics.Debug.WriteLine(string.Format(objField.ToString()));
    }
    This'll return the value of all fields after construction, providing the class has a constructor with no arguments.

    As far as I know there's no way of detecting what the value is set to before the class has been instansiated. This isn't stored in the metadata : it's part of the source so you have to JIT and run the constructor first before getting the value.

    This should do the trick.

    Darwen.
    Last edited by darwen; February 11th, 2005 at 02:12 AM.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  7. #7
    Join Date
    Mar 2004
    Location
    Prague, Czech Republic, EU
    Posts
    1,701

    Lightbulb Re: Using reflection to retrieve the default field value

    I see shorter solution:

    Code:
    Type = typeof(TestClass)
    t.GetField("m_nValue", BindingFlags.Static | BindingFlags.NonPublic).GetValue(t)
    and ups ... your 10 is here.
    • Make it run.
    • Make it right.
    • Make it fast.

    Don't hesitate to rate my post.

  8. #8
    Join Date
    Nov 2004
    Location
    Poland
    Posts
    1,355

    Re: Using reflection to retrieve the default field value

    and ups ... your 10 is here.
    U mean oops?

  9. #9
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Using reflection to retrieve the default field value

    You can't do this for non-static (or non-const) fields. You can of course do this for static fields.

    And the 'foreach' loop was there because they used one.

    In order to get the value of a non-static field you have to create an instance of the object first : which is I believe what I said.

    And the example I gave was designed to be generic i.e. you can pass any type into it :

    Code:
    public class DefaultValueReflector
    {
        static public Hashtable GetNonStaticDefaultValues(Type type)
        {
            Hashtable hashFieldToValue = new Hashtable();
    
            ConstructorInfo infoConstructor = type.GetConstructor(Type.EmptyTypes);
            TestClass testClass = infoConstructor.Invoke(new object[0] { }) as TestClass;
    
            FieldInfo[] aFieldInfo = type.GetFields( BindingFlags.Instance | 
                    BindingFlags.Public | 
                    BindingFlags.NonPublic | 
                    BindingFlags.DeclaredOnly );
    
            foreach (FieldInfo infoField in aFieldInfo)
            {
    	    object objField = infoField.GetValue(testClass);
    	    hashFieldToValue[infoField.Name, objField]
            }
    
            return hashFieldToValue;
        }
    
        static public Hashtable GetStaticDefaultValues(Type type)
        {
            Hashtable hashFieldToValue = new Hashtable();
    
            FieldInfo[] aFieldInfo = type.GetFields( BindingFlags.Static | BindingFlags.Public |
    			BindingFlags.NonPublic | BindingFlags.DeclaredOnly );
    
            foreach (FieldInfo infoField in aFieldInfo)
            {
    	object objField = infoField.GetValue(type);
    	hashFieldToValue[infoField.Name, objField]
            }
    
            return hashFieldToValue;
        }
    }
    If you're interested in the value of a const : why use the word "Default". "Default" implies that the value can change and so therefore can't be const.

    To get the value of a field you already know the name of, then replace the 'aFieldInfo' bits with boudino's suggestion : only on the non-static one pass in the instance of the class to GetValue.

    Darwen.

    Darwen.
    Last edited by darwen; February 11th, 2005 at 05:03 AM.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using reflection to retrieve the default field value

    Thanks, everyone, I'll try it out.

    Arjay

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured