views:

386

answers:

3

If you have a property defined like this:

private DateTime modifiedOn;
public DateTime ModifiedOn
{
    get { return modifiedOn; }
}

How do you set it to a certain value with Reflection?

I've tried both:

dto.GetType().GetProperty("ModifiedOn").SetValue(dto, modifiedOn, null);

and

dto.GetType().GetProperty("modifiedOn").SetValue(dto, modifiedOn, null);

but without any success. Sorry if this is a stupid question but it's the first time I'm using Reflection with C#.NET.

+6  A: 

That has no setter; you'd need:

public DateTime ModifiedOn
{
    get { return modifiedOn; }
    private set {modifiedOn = value;}
}

(you might have to use BindingFlags - I'll try in a moment)

Without a setter, you'd have to rely on patterns / field names (which is brittle), or parse the IL (very hard).

The following works fine:

using System;
class Test {
    private DateTime modifiedOn;
    public DateTime ModifiedOn {     
        get { return modifiedOn; }
        private set { modifiedOn = value; }
    }
}
static class Program {
    static void Main() {
        Test p = new Test();
        typeof(Test).GetProperty("ModifiedOn").SetValue(
            p, DateTime.Today, null);
        Console.WriteLine(p.ModifiedOn);
    }
}

It also works with an auto-implemented property:

public DateTime ModifiedOn { get; private set; }

(where relying on the field-name would break horribly)

Marc Gravell
Cool, hadn't thought about being able to have private in front of the setter. And I'll have to check those BindingFlags I guess. Thx.
Lieven Cardoen
It looks like you only need `BindingFlags` if the entire property is private.
Marc Gravell
Still doesn't work so I guess I'll have to use those BindingFlags?
Lieven Cardoen
Define "doesn't work" - what happens? The example I posted works fine... also: are you using CF? Silverlight? or regular .NET? (it matters...)
Marc Gravell
One moment, may have forgotten something.
Lieven Cardoen
Ok, got it to work. Thx.
Lieven Cardoen
+1  A: 

If your property doesn't have a setter, you can't call SetValue on it.

Tommy Carlier
+1  A: 

You could try to set the backing field and not the property; you should use GetField() not GetProperty().

Kindness,

Dan

Daniel Elliott
While that would work, accessing fields is *generally* an even-more brittle form of reflection. For example, what happens when somebody discovers C# 3.0 and makes it: `public DateTime ModifiedOn { get; private set; }` ?
Marc Gravell