Simple equivalent of “With” statement in C#

Consider the following class in C#

	public class Person
	{
		private string name;
		private int age;
		
		public string Name{
			get {return name;}
			set { name = value; }
		}
		
		public int Age{
			get {return age;}
			set { age = value; }
		}
	}

If I want to set the value of Name and Age property on the instance of Person class, I’ll need to refer to that instance for every property I need to set in the code. For example:

var person = new Person();
person.Name = "Super Man";
person.Age = 30;

It would have been great if C# had an equivalent of VB’s “With..End” statement, where we could refer to the instance of Person class only once and then refer to properties only.

Today, I came across this post “mucking about with hashes…“, which shows how C# lambdas could be used as hashes. Using this concept, I implemented a simple extension method that simulates the behavior of VB’s “With..End” statement to some extent.

Here is the code for extension method:

	public static class MetaExtensions
	{	
		public static void Set(this object obj,params Func<string,object>[] hash){
				foreach(Func<string,object> member in hash){
					var propertyName = member.Method.GetParameters()[0].Name;
					var propertyValue = member(string.Empty);
					obj.GetType()
						.GetProperty(propertyName)
							.SetValue(obj,propertyValue,null);
				};
		}
	}

Using this extension method, we can set the value of properties on instance of Person class as follows:

var person = new Person();
person.Set(
	Name => "Super Man",
	Age => 30
);

Isn’t that cool?

Comments

  1. Ilia Jerebtsov says:

    Nothing like summoning the full power of reflection and runtime evaluation to make your code look slightly better.

  2. Uhm….

    var person = new Person()
    {
    Name = “John”,
    Age = 30
    };

    Did you not try that first?

  3. Gordon says:

    This is already in C#:

    var person = new Person() { Name=”superman”, Age=30 };

  4. (Stolen from proggit) says:

    var person = new Person()
    {
    Name = “Super Man”,
    Age = 30
    };
    // No tricks or performance penalties…

  5. Anay says:

    Thanks a lot guys for your valuable comments. Let me clarify few points here:

    1) The idea of this post is not to get this feature in mainstream development. I personally hate use of reflections while developing as they create problems while debugging the code. But in case you are working on building a DSL, then such ideas do help a lot. Overall, that depends on design decisions.

    2) C# does provide feature to set values for properties while creating the instance of a particular class as mentioned in the comments. This feature allows to set property values only at the time of creating the instance. It cannot be used to change the values of multiple properties later.

    I feel I should have mentioned this in the post to avoid confusion. Apologies.

  6. chris Donnan says:

    In my current project we have an extension called With that we use a little differently. We are interested in using it to return the same value:

    public static T With(this T t, Action action) {
    action(t);
    return t;
    }

    var z = new Zed(“ctorArg1″,2,3).With(m => m.PropX = 234);

    Different, but very useful and related.

  7. Chris says:

    Thank you for this, I’ve been looking for something like this for a while. Very useful, however the big draw back of this method is that it lacks intellisense;

    for instance I have (where this.Event is a property of type Event)
    var event = this.Event;
    person.Set(
    Name => “SomeName”;
    );

    this works but Name or any other attributes of the class Event don’t show up, is there a way to fix/alter this so intellisense will work?

    Others very useful thank you.

  8. Anay says:

    Hi Chris,

    Any DSL implementation like this would mean that you won’t be able to enjoy some features provided by IDE. You need to loose something to gain something right?

  9. David Blaine Fullerton says:

    I really love your idea. I submitted this as a suggestion for the next VS 2010. I will try to give you my link, if possible. Trust me, you’ve got it right. They need to change the LANGUAGE SYNTAX to allow this funcitonality. Here is my suggestion, based on your work.

    https://connect.microsoft.com/VisualStudio/feedback/details/553763/change-language-syntax-of-c-to-allow-with-end-feature-like-in-vb

  10. Anay says:

    Hi David,

    Thanks for your comment. It’s nice that you liked this idea and used it to make a suggestion.

  11. Interesting idea. I wrote a [blog](http://blog.baltrinic.com/software-development/dotnet/c-equivalent-for-visual-basic-with-statement) some time back that took a similar approach but didn’t use reflection. I like your syntax better but people might find mine a little simpler and possible faster.

Speak Your Mind

*