JsonProperty特性构造调用中设置属性值的原理及C#语法疑问
关于C#特性中
[JsonProperty("id", Required = Required.Always)]写法的解惑 嘿,这个问题问得特别到位!我当初第一次碰到特性的这种混合写法时也愣了一下,咱们把它拆解开讲就清楚了:
首先明确:这种构造参数+命名参数的写法是C#语言专门为特性声明设计的特殊语法,普通类的实例化没法这么用,它属于C#本身对特性的语法支持,不是Attribute基类的特殊机制。
咱们拆解这段代码的两个部分:
"id"部分:这是直接传入JsonPropertyAttribute构造函数的位置参数,对应你看到的public JsonPropertyAttribute(string propertyName);构造方法,用来初始化特性的必填核心参数。Required = Required.Always部分:这是C#特性特有的命名参数语法,用来给特性类的**公共属性(或公共字段)**赋值。只要JsonPropertyAttribute有一个可访问的Required属性(不管构造函数有没有包含这个参数),你就能在特性声明的括号里用这种方式设置它的值。
背后的原理
当编译器处理特性声明时,会先调用对应的构造函数创建特性实例,然后通过反射把命名参数对应的属性/字段逐一赋值。换句话说,这段代码的效果等价于(但语法上是C#特性专属的):
var attr = new JsonPropertyAttribute("id"); attr.Required = Required.Always;
只不过特性声明的语法把这两步合并到了方括号里的写法中。
举个自定义特性的例子
为了更直观,咱们自己写个特性试试:
public class UserInfoAttribute : Attribute { // 构造函数的必填参数 public string Username { get; } // 可通过命名参数设置的公共属性 public int Age { get; set; } public bool IsActive { get; set; } public UserInfoAttribute(string username) { Username = username; } }
然后就可以用同样的语法声明特性:
[UserInfoAttribute("johndoe", Age = 28, IsActive = true)] public class User { }
完全和你碰到的JsonProperty写法逻辑一致。
关键注意点
- 这种写法仅适用于特性声明,普通类实例化时不能这么写(普通类要设置属性得用对象初始化器
new ClassName() { Prop = Value },和特性的语法位置不一样)。 - 命名参数只能对应特性类的公共成员(公共属性或公共字段),私有成员没法这么设置。
内容的提问来源于stack exchange,提问作者Tristan Trainer
相关产品推荐
相关产品推荐

