Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set value for property of an anonymous object?

this is my code for example:

var output = new {     NetSessionId = string.Empty };  foreach (var property in output.GetType().GetProperties()) {     property.SetValue(output, "Test", null); } 

It occurs an exception: "Property set method not found". I want to know how to create an anonymous type with properties which can be set.

Thanks.

like image 396
Leo Vo Avatar asked Jul 03 '13 06:07

Leo Vo


People also ask

How do you initialize an anonymous object?

You create anonymous types by using the new operator together with an object initializer. For more information about object initializers, see Object and Collection Initializers. The following example shows an anonymous type that is initialized with two properties named Amount and Message .

Which of the following selects an anonymous type?

In LINQ, select clause generates anonymous type so that in a query you can include properties that are not defined in the class.

What is an anonymous object in C#?

In C#, an anonymous type is a type (class) without any name that can contain public read-only properties only. It cannot contain other members, such as fields, methods, events, etc. You create an anonymous type using the new operator with an object initializer syntax.


2 Answers

Anonymous type properties are read only and they cannot be set.

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.

Anonymous Types (C# Programming Guide)

like image 181
MarcinJuraszek Avatar answered Sep 19 '22 15:09

MarcinJuraszek


How to set value for property of an anonymous object?

Because I was reminded today that nothing is truly immutable when using reflection in combination with knowledge on how certain things are implemented (backing fields for the read-only properties of anonymous types in this case), I thought it wise to add an answer illustrating how the property values of an anonymous object can be changed, by mapping them to their backing fields.

This method relies on a specific convention used by the compiler for naming these backing fields: <xxxxx>i__Field in .NET and <xxxxx> on Mono, with the xxxxx representing the property name. If this convention were to change, the code below will fail (note: it will also fail if you try to feed it something that is not an anonymous type).

public static class AnonymousObjectMutator {     private const BindingFlags FieldFlags = BindingFlags.NonPublic | BindingFlags.Instance;     private static readonly string[] BackingFieldFormats = { "<{0}>i__Field", "<{0}>" };      public static T Set<T, TProperty>(         this T instance,         Expression<Func<T, TProperty>> propExpression,         TProperty newValue) where T : class     {         var pi = (propExpression.Body as MemberExpression).Member;         var backingFieldNames = BackingFieldFormats.Select(x => string.Format(x, pi.Name)).ToList();         var fi = typeof(T)             .GetFields(FieldFlags)             .FirstOrDefault(f => backingFieldNames.Contains(f.Name));         if (fi == null)             throw new NotSupportedException(string.Format("Cannot find backing field for {0}", pi.Name));         fi.SetValue(instance, newValue);         return instance;     } } 

Sample:

public static void Main(params string[] args) {     var myAnonInstance = new {          FirstField = "Hello",          AnotherField = 30,      };     Console.WriteLine(myAnonInstance);      myAnonInstance         .Set(x => x.FirstField, "Hello SO")         .Set(x => x.AnotherField, 42);     Console.WriteLine(myAnonInstance); } 

With output:

{ FirstField = Hello, AnotherField = 30 } { FirstField = Hello SO, AnotherField = 42 } 

A slightly more elaborate version can be found here

like image 28
Alex Avatar answered Sep 16 '22 15:09

Alex