C#:指定自动属性时会发生什么情况?
我了解到,在C#中有一个叫做autoproperty的东西,如果我声明一个变量,它通常由编译器自动生成,如: 公共列表myList{get;set;}C#:指定自动属性时会发生什么情况?,c#,properties,C#,Properties,我了解到,在C#中有一个叫做autoproperty的东西,如果我声明一个变量,它通常由编译器自动生成,如: 公共列表myList{get;set;} public class MyClass { private List<int> myList; public List<int> MyList { get { return this.myList; } set
public class MyClass
{
private List<int> myList;
public List<int> MyList
{
get
{
return this.myList;
}
set
{
this.myList = value;
}
}
}
公共类MyClass
{
私人名单;
公共列表列表
{
得到
{
返回此.myList;
}
设置
{
this.myList=值;
}
}
}
它允许我访问变量,如:
List<int> a = myInstance.MyList;
List a=myInstance.MyList;
所以它像函数一样工作,但像普通对象一样被调用。
但是在一个项目上真正分配的是什么呢?对象myList上是否分配了“深层链接”,或者get函数上是否分配了类似“函子”的内容?
我的意思是,如果我使用a,get函数每次都会被调用吗
我问这个问题的原因是:如果我在多线程情况下使用这个函数,在get和set函数中对对象进行一些锁定,我不想绕过锁定。所以,如果我首先将myList指定给一个,然后使用它,它将不再被锁定?我说得对吗?属性的名称最好是
List getValue()
和setValue(List value)
函数对。有一些次要属性:
- 他们在沉思中出现
- 它们可以在接口/抽象类中声明
- 它们像字段一样使用,但在极少数情况下除外(out和ref参数)
MyList
很难混淆MyList
和MyList
很容易混淆
但是a
上真正分配的是什么
a
的类型是List
,列表是引用类型,因此变量包含对列表的引用C#不会对你撒谎。变量的类型就是变量的类型
它的工作原理类似于函数,但其调用方式类似于普通对象
这句话毫无意义,它向我表明你对C#的工作原理有些误解。“对象”不是“调用”的对象,除非它们是委托。听起来您混淆了属性、变量、对象和委托了解这些东西是什么。如果你不知道所有部件的正确名称,就很难在C#编程中取得成功
我想你想说的是,属性是一个成员,它像字段一样被访问,但是属性的读写是作为对成员访问方法的调用来实现的
我的意思是,如果我使用a
,是否每次都会再次调用get函数
您可以自己尝试回答这个问题:
myInstance.MyList = new List<int> { 10, 20, 30 };
List<int> a = myInstance.MyList;
myInstance.MyList = new List<int> { 100, 200, 300 };
Console.WriteLine(a[0]);
myInstance.MyList=新列表{10,20,30};
列表a=myInstance.MyList;
myInstance.MyList=新列表{100200300};
Console.WriteLine(a[0]);
如果a
再次获取属性,则该属性应为100。如果没有,则应为10。对将会发生的事情做出预测,然后尝试一下,看看你是否正确
如果我在多线程情况下使用它,并在get和set函数中锁定对象,我不想绕过锁定。因此,如果我首先将MyList
分配给a
,然后使用它,它将不再被锁定?我说得对吗
对。我将借此机会指出,制作公开必须锁定的对象的公共接口是一种极为糟糕的编程实践。更好的选择是:
- 不要编写多线程程序。要把它们弄对真的很难
- 如果必须,请不要编写跨线程共享内存的多线程程序
- 如果必须共享内存,请始终使用线程安全集合
myInstance.MyList
分配给a
时,调用MyList
get属性,该属性将引用MyList
复制到a
中。如果您随后使用a
,您将直接使用私有myList
引用的列表。只有在实际调用get属性时,才能通过它
这基本上失去了myList的私有性。如果要强制调用方通过执行锁定等操作的函数,则必须为要允许的操作编写函数,如添加到列表中,而不向调用方公开实际列表
对于线程安全操作,无需在C#中执行此操作-您应该使用免费实现这些操作的。否,它绝对不会将对字段的引用放入变量中。它将字段的值放入变量中,该值是一个引用!非常非常重要的是,你要理解其中的区别。这个答案的第一段中几乎没有什么是正确的。我们可以在C#7中得到一个字段的引用:
类C{private int f;public ref int M()=>ref this.f;}
,现在我们得到了一个字段的引用。但这与引用类型字段的内容大不相同。感谢Eric Lippert指出我的错误语言,我已编辑以更正该错误。我确实理解其中的区别,只是解释得不好。