In C#, how to access curly brace constructor using

2020-06-06 00:59发布

In C# we can now construct new objects using the curly brace constructor, i.e.

class Person {
   readonly string FirstName {get; set;}
   readonly string LastName {get; set;}
}

new Person { FirstName = "Bob", LastName = "smith" }

I need to construct this object using reflection, but if these member variables are marked readonly, I can only set them in the constructor, and there is only the curly-brace constructor available. Is there some way I can access the curly-brace-style constructor using reflection? Thanks.

4条回答
Evening l夕情丶
2楼-- · 2020-06-06 01:26

First, properties cannot be marked read-only with the readonly keyword. They can only have non-public setter methods*).

Second, there's no such thing as a “curly brace constructor”. It's just a syntactic sugar (a shortcut) for a set of statements like this:

Person p = new Person();  // standard parameterless constructor is called
p.FirstName = "Bob";
p.LastName = "Smith";

Note that you could also use a constructor with parameters:

new Person(1, 2, 3) { FirstName = "Bob", LastName = "Smith" }

gets translated as:

Person p = new Person(1, 2, 3);
p.FirstName = "Bob";
p.LastName = "Smith";

Regarding reflection: To construct a new instance and initialize it in the same way as in the new Person { FirstName = "Bob", LastName = "Smith" } example you have to:

  1. retrieve the constructor (see Type.GetConstructor) and call it or use Activator.CreateInstance to instantiate the type,
  2. retrieve the FirstName property (see Type.GetProperty),
  3. set it (see PropertyInfo.SetValue),
  4. repeat (2) and (3) for LastName.

*) Update: C# 9 will (as of May 2020) introduce init-only properties, which will be the equivalent of readonly fields, allowing property assignment during object initialization only (i.e. in the constructor or in an object initializer).

查看更多
叛逆
3楼-- · 2020-06-06 01:27

This has no relation to constructor. This is simply short-handed syntax to initialize normal properties.

new Person { FirstName = "Bob", LastName = "smith" };

is exactly same as

var person = new Person();
person.FirstName = "Bob";
person.LastName = "smith";

And as people said. Your example wont compile. Because its not constructor.

查看更多
爷的心禁止访问
4楼-- · 2020-06-06 01:38

How can you compile this? C# reports an error:

error CS0106: The modifier 'readonly' is not valid for this item
查看更多
Root(大扎)
5楼-- · 2020-06-06 01:41

I'm guessing you mean private poperty setters instead of readonly properties (the get and set are shorthand for full getters and setters). Then you will have to do something like this to set the properties reflectively:

Type personType= typeof(Person);
object personInstance = Activator.CreateInstance(personType);
personInstance.GetProperty("FirstName").SetValue(classObject, "Bob, null);
personInstance.GetProperty("LastName").SetValue(classObject, "smith, null);
查看更多
登录 后发表回答