C# 对象初始化程序将初始化只读属性,但仅适用于非原始类型
C# object initializer will initialize read only properties, but for non-primitive types only
在下面的测试代码中我不明白为什么第一行TestMethod
是合法的,而剩下的两行是不合法的:
public class Bar
{
public string Prop { get; set; }
}
public class Foo
{
public int Primitive { get; } = 0;
public Func<int, int> Function { get; } = (i) => i;
public Bar Bar { get; } = new Bar();
}
public class TestClass
{
public void TestMethod()
{
var baz = new Foo { Bar = { Prop = "Hello World!" } }; // legal
var buzz = new Foo { Primitive = 1 }; // Property or indexer 'Foo.Primitive' cannot be assigned to -- it is read only
var fuzz = new Foo { Function = (i) => 2 }; // Property or indexer 'Foo.Function' cannot be assigned to -- it is read only
}
}
如果在对象初始值设定项中分配给 class 类型的只读属性如 Bar
是合法的(它是;这是有道理的,因为 'read only' 确实意味着'read only except at class construction time' 在 C# 中,据我所知)那么为什么分配给类型为 int
和 Func<int, int>
的属性是非法的?
这似乎更加令人困惑,因为(再次,据我了解)Func<int, int>
是引用类型,如 Bar
属性 但不同于 int
属性.
var baz = new Foo { Bar = { Prop = "Hello World!" } }; // legal
这不是对 Bar
的 分配 。它本质上是:
var tmp = new Foo();
tmp.Bar.Prop = "Hello World!";
var baz = tmp;
.Bar
从未分配给。
相反,然而:
var buzz = new Foo { Primitive = 1 };
是:
var tmp = new Foo();
tmp.Primitive = 1;
var buzz = tmp;
分配给 .Primitive
。
If it is legal to assign to class-type read only properties like Bar in an object initializer (which it is [...])
不,不是。对象初始值设定项调用构造函数,然后分配给属性。例如,这段代码:
var buzz = new Foo { Primitive = 1 };
只是语法糖:
var buzz = new Foo();
buzz.Primitive = 1;
如果 Primitive
是只读 属性,则无效。
(说句迂腐话,一般认为是赋值给一个临时局部变量,设置属性,最后赋值给buzz
更合适,但是我们忽略现在。)
您观察到的工作代码并未设置那些只读属性 - 它是 获取 它们,然后使用返回的引用设置值。所以这个:
var baz = new Foo { Bar = { Prop = "Hello World!" } }
实际上等同于:
var baz = new Foo();
baz.Bar.Prop "Hello World!";
这是完全有效的,即使 Bar
是只读的。
在下面的测试代码中我不明白为什么第一行TestMethod
是合法的,而剩下的两行是不合法的:
public class Bar
{
public string Prop { get; set; }
}
public class Foo
{
public int Primitive { get; } = 0;
public Func<int, int> Function { get; } = (i) => i;
public Bar Bar { get; } = new Bar();
}
public class TestClass
{
public void TestMethod()
{
var baz = new Foo { Bar = { Prop = "Hello World!" } }; // legal
var buzz = new Foo { Primitive = 1 }; // Property or indexer 'Foo.Primitive' cannot be assigned to -- it is read only
var fuzz = new Foo { Function = (i) => 2 }; // Property or indexer 'Foo.Function' cannot be assigned to -- it is read only
}
}
如果在对象初始值设定项中分配给 class 类型的只读属性如 Bar
是合法的(它是;这是有道理的,因为 'read only' 确实意味着'read only except at class construction time' 在 C# 中,据我所知)那么为什么分配给类型为 int
和 Func<int, int>
的属性是非法的?
这似乎更加令人困惑,因为(再次,据我了解)Func<int, int>
是引用类型,如 Bar
属性 但不同于 int
属性.
var baz = new Foo { Bar = { Prop = "Hello World!" } }; // legal
这不是对 Bar
的 分配 。它本质上是:
var tmp = new Foo();
tmp.Bar.Prop = "Hello World!";
var baz = tmp;
.Bar
从未分配给。
相反,然而:
var buzz = new Foo { Primitive = 1 };
是:
var tmp = new Foo();
tmp.Primitive = 1;
var buzz = tmp;
分配给 .Primitive
。
If it is legal to assign to class-type read only properties like Bar in an object initializer (which it is [...])
不,不是。对象初始值设定项调用构造函数,然后分配给属性。例如,这段代码:
var buzz = new Foo { Primitive = 1 };
只是语法糖:
var buzz = new Foo();
buzz.Primitive = 1;
如果 Primitive
是只读 属性,则无效。
(说句迂腐话,一般认为是赋值给一个临时局部变量,设置属性,最后赋值给buzz
更合适,但是我们忽略现在。)
您观察到的工作代码并未设置那些只读属性 - 它是 获取 它们,然后使用返回的引用设置值。所以这个:
var baz = new Foo { Bar = { Prop = "Hello World!" } }
实际上等同于:
var baz = new Foo();
baz.Bar.Prop "Hello World!";
这是完全有效的,即使 Bar
是只读的。