Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing an expression tree to read the name and value of a property. Is there an alternative?
    primarykey
    data
    text
    <p><strong>Assumptions</strong></p> <p>Suppose I have a class with a property:</p> <pre><code>class ClassWithProperty { public string Prop { get; private set; } public ClassWithProperty(string prop) { this.Prop = prop; } } </code></pre> <p>And now suppose I have created an instance of that class:</p> <pre><code>var test = new ClassWithProperty("test value"); </code></pre> <p><strong>What I want</strong></p> <p>I want this printed out to the console:</p> <pre><code>Prop = 'test value' </code></pre> <p>Piece of cake! I use this code to produce the wanted output:</p> <pre><code>Console.WriteLine("Prop = '{1}'", test.Prop); </code></pre> <p><strong>Problem</strong></p> <p>I am violating DRY, because "Prop" appears twice in the code above. If I refactor the class and change the name of the property, I also have to change the string literal. There is also a lot of boilerplate code, if I had a class with many properties.</p> <p><strong>Proposed solution</strong></p> <pre><code>string result = buildString(() =&gt; c.Prop); Console.WriteLine(result); </code></pre> <p>Where the buildString method looks like this:</p> <pre><code>private static string buildString(Expression&lt;Func&lt;string&gt;&gt; expression) { MemberExpression memberExpression = (MemberExpression)expression.Body; string propertyName = memberExpression.Member.Name; Func&lt;string&gt; compiledFunction = expression.Compile(); string propertyValue = compiledFunction.Invoke(); return string.Format("{0} = '{1}'", propertyName, propertyValue); } </code></pre> <p><strong>Question</strong></p> <p>The above solution works fine and I am happy with it, but if there is some more easier and less "scary" way to solve this, that would make me much happier. Is there some easier alternative to achieve the same result with less and simpler code? Maybe something without expression trees?</p> <p><strong>Edit</strong></p> <p>Based on Manu's fine idea (see below) I could use this extension method:</p> <pre><code>static public IEnumerable&lt;string&gt; ListProperties&lt;T&gt;(this T instance) { return instance.GetType().GetProperties() .Select(p =&gt; string.Format("{0} = '{1}'", p.Name, p.GetValue(instance, null))); } </code></pre> <p>It's great for getting a string representation for all properties for an instance.</p> <p>But: From this enumeration, how could I pick type-safely a specific property? Again I would use expression trees ... or am I not seeing the wood for the trees?</p> <p><strong>Edit 2</strong></p> <p>Using reflection or expression trees here is a matter of taste.</p> <p>Luke's idea using projection initializers is just brilliant. From his answer I finally build this extension method (which is basically just a LINQ'd version of his answer):</p> <pre><code>public static IEnumerable&lt;string&gt; BuildString(this object source) { return from p in source.GetType().GetProperties() select string.Format("{0} = '{1}'", p.Name, p.GetValue(source, null)); } </code></pre> <p>Now a call will look like this:</p> <pre><code>new { c.Prop }.BuildString().First() </code></pre> <p>Which looks a bit nicer than the my original call with a lambda (but this is also a matter of taste I guess). Luke's suggestion is however superior to my solution, since it allows specifying as many properties as you like (see below).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload