如果在C#自动属性中get和set都是强制的,为什么我必须打扰指定“get; set;”在所有?C#自动属性 - 为什么我必须写“get; set;”?
回答
错误:属性或索引器不可能会作为传出或引用参数
传递如果没有指定{get; set;}
那么编译器将不知道这是否是一个字段或属性。 这很重要,因为当它们“看起来”相同时,编译器会以不同的方式处理它们。例如在属性上调用“InitAnInt”会引发错误。
class Test
{
public int n;
public int i { get; set; }
public void InitAnInt(out int p)
{
p = 100;
}
public Test()
{
InitAnInt(out n); // This is OK
InitAnInt(out i); // ERROR: A property or indexer may not be passed
// as an out or ref parameter
}
}
你不应该创建公共字段/于类变量,你永远不知道什么时候你会想改变它有让&组访问,然后你不知道你要什么码打破,特别是如果你有客户对您的API进行编程。
另外,您可以为get &集合设置不同的访问修饰符,例如, {得到; private set;}使get public和set为private声明类。
因为你可能需要一个只读属性:
public int Foo { get; private set; }
或者只写属性:
public int Foo { private get; set; }
编译器需要知道,如果你想让它生成getter和/或一个二传手,或者可能正在宣布一个领域。
因为你需要一些方法来区分它与普通的领域。
具有不同访问修饰符也是有用的,例如,
public int MyProperty { get; private set; }
如果该属性没有访问器,编译器如何将它与字段分开?什么将它与田地分开?
只是想我会分享我对这个主题的发现。
编码属性如下,是一个.net 3.0快捷方式调用“自动执行的属性”。
public int MyProperty { get; set; }
这可以为您节省一些打字费用。申报财产的很长的路是这样的:
private int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
当您使用“自动实现的属性”,编译器生成的代码线了get和set一些“k_BackingField”。下面是使用反射器的反汇编代码。
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
[CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
拆卸C#代码从IL
另外导线开setter和getter的方法。
[CompilerGenerated]
public void set_MyProperty(int value)
{
this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
return this.<MyProperty>k__BackingField;
}
从IL拆卸C#代码
在声明只读自动实现的属性,通过设置器,以私人:
public int MyProperty { get; private set; }
所有的编译器标志“ 套“作为私人。 setter和getter方法也是一样的。
public int MyProperty
{
[CompilerGenerated]
get
{
return this.<MyProperty>k__BackingField;
}
private [CompilerGenerated]
set
{
this.<MyProperty>k__BackingField = value;
}
}
从IL拆卸C#代码
所以我不知道为什么需要框架将Get;并设置;在自动实施的财产上。如果没有提供set和setter方法,他们可能就没有写过。但是,我不知道,可能会有一些编译器级别的问题让我感到困难。
如果你看一下声明只读属性的很长的路要走:
public int myProperty = 0;
public int MyProperty
{
get { return myProperty; }
}
再看看反汇编代码。二传手根本就没有。
public int Test2
{
get
{
return this._test;
}
}
public int get_Test2()
{
return this._test;
}
拆卸C#从IL
好代码,显然,你需要字段和属性之间的多义性的一种方式。但是必需的关键字是否真的有必要例如,很明显,这两个声明是不同的:
public int Foo;
public int Bar { }
这可以工作。也就是说,这是编译器可以想象的一种语法。
但是,你会遇到空块具有语义含义的情况。这似乎不稳定。
由于没有人提到它...你可以做自动虚拟财产和重写它:
public virtual int Property { get; set; }
如果没有的get/set,如何将它被覆盖?请注意,您被允许override the getter and not the setter:
public override int Property { get { return int.MinValue; } }
而且,因为自从C#6.0(在Visual Studio 2015年,在这个答案在版本最终预览可用时),你可以实现一个真正的只读属性:
public string Name { get; }
public string Name { get; } = "This won't change even internally";
...相对于目前的解决方法不完善与公共的吸气/私人设定器对:
public string Name { get; private set; }
public Constructor() { Name="As initialised"; }
public void Method() { Name="This might be changed internally. By mistake. Or not."; }
低于上述实施例(编译和executa ble online here)。
using System;
public class Propertier {
public string ReadOnlyPlease { get; private set; }
public Propertier() { ReadOnlyPlease="As initialised"; }
public void Method() { ReadOnlyPlease="This might be changed internally"; }
public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); }
}
public class Program {
static void Main() {
Propertier p=new Propertier();
Console.WriteLine(p);
// p.ReadOnlyPlease="Changing externally!";
// Console.WriteLine(p);
// error CS0272: The property or indexer `Propertier.ReadOnlyPlease' cannot be used in this context because the set accessor is inaccessible
// That's good and intended.
// But...
p.Method();
Console.WriteLine(p);
}
}
其他有关C#6的好消息。0可作为官方预览视频here。
- 1. 为什么自动实现的属性必须同时定义get和set访问
- 2. 自动实现的属性必须同时定义get和set访问器
- 3. 目标属性必须是依赖属性 - 为什么?
- 4. 什么时候在C#中使用get和set属性?
- 5. 为什么我们必须提供boost :: get的参数类型?
- 6. 为什么必须使用Set来保存对象?
- 7. 为什么我必须在通用类
- 8. 自动生成的属性{get; set;} vs {get;私人或保护集;}在C#
- 9. 在apex中定义get和set的自动属性有什么意义?
- 10. 访问者为什么必须比属性限制更多?
- 11. 从Get属性引用Set属性
- 12. 为什么我必须使用-lstdC++ fs?
- 13. 为什么选择自动属性?
- 14. 我们必须在函数“return”的末尾写什么?在C++
- 15. 为什么我用@Override获得“必须重写超类方法”?
- 16. 为什么这个alignment属性必须在typedef中指定?
- 17. 为什么WEKA-TestSets必须具有类属性?
- 18. 为什么视图属性必须分配给变量?
- 19. KindError:属性r必须是SecondModel的实例,为什么?
- 20. 为什么我必须逃脱最终]
- 21. 为什么我必须删除[close_out out_channel]?
- 22. 为什么我必须声明var = Class.new?
- 23. 为什么我们必须综合?
- 24. 为什么我必须转换变量?
- 25. 为什么@synthetize必须手动添加?
- 26. 什么是python属性get和set命令?
- 27. 我必须手动释放声明为保留的属性吗?
- 28. 为什么我们必须写头缓存控制?
- 29. 为什么我必须填写此参数值
- 30. 我怎么装饰与DISPID属性(get和set?都不是?)
您还可以添加各种修饰符,如受保护等。 – Tigraine 2008-12-04 13:15:42
是的,还有其他人说的......您需要一种方法来区分字段和属性。 – 2008-12-04 13:19:50
有点旁注:有只读字段的概念。该框架将确保这些只写入一次。它与私人制片人或获得者不同,如果你有权限的话可以写出来。 – 2008-12-04 13:24:38