views:

166

answers:

3

Let's assume I have a class ClassWithMember

class ClassWithMember
{
    int myIntMember = 10;
}

How do I get the default value 10 of the myIntMember member by System.Type?

I'm currently struggling around with reflections by all I retreive is the default value of int (0) not the classes default member (10)..

+2  A: 

Try creating an instance an retreive the value with reflection.

Henrik Jepsen
Unwillingly, since I also use classes (MonoBehaviour from Unity3D) that can't be instantiated that easy.
Ruben Aster
Just to elaborate: the default value of any int is 0, the assignment of your int to 10 is compiled as an assignment instruction in the constrictor, hence reflection is your choice, unless you want to refactor to "static readonly int DefaultValue = 10" and "myIntMember = DefaultValue"
Michael Stum
Reflection would be great but I don't get to the point where I get this specific value by type.
Ruben Aster
@Ruben If you can't instantiate the class, then it's a problem. You could in theory use Reflection to get the method body of the constructor and decompile the IL Code (Similar to how Reflector works), but that quite prone to breaking if the library changes.
Michael Stum
That's ok since it's only used inside the editor not the game-application itself.
Ruben Aster
+2  A: 

You can try something like this:

var field = typeof(ClassWithMember).GetField("myIntMember",
    BindingFlags.Instance | BindingFlags.NonPublic);
var value = (int)field.GetValue(new ClassWithMember());

The trick here is to instantiate an instance.

Anne Sharp
+1  A: 

Hi Ruben,

If you're in control of the code for ClassWithMember, you could take a completely different approach to this by using the [DefaultValue] attribute from System.ComponentModel. Basically, what you'd do is write something like this:

class ClassWithMember
{
    public ClassWithMember()
    {
        SetDefaultValues();
    }

    [DefaultValue(5)]
    public MyIntMember { get; set; }
}

And then have a function like this somewhere, perhaps in a base class:

public void SetDefaultValues()
{
    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this))
    {
        DefaultValueAttribute a = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
        if (a == null) 
            continue;
        prop.SetValue(this, a.Value);
    }
}

So now, you have a situation where you can easily retrieve the default values using Reflection.

Keep in mind that this is going to be quite a lot slower due to the Reflection requirement, so if this code gets instantiated a lot, you'll probably want to find a different approach. Also, it won't work with non-value types, due to a limitation with the .NET Framework's attribute support.

Warren
Had a look at this approuch, too. But unfortunately I'm not in control of every class.
Ruben Aster