我了解到,在C#中有一个称为自动属性的东西,如果我声明了以下变量,它通常由编译器自动生成: 公开清单myList {get;组; }
public class MyClass
{
private List<int> myList;
public List<int> MyList
{
get
{
return this.myList;
}
set
{
this.myList = value;
}
}
}
它使我可以像这样访问变量:
List<int> a = myInstance.MyList;
因此,它像函数一样工作,但被称为普通对象。 但是,什么是真正分配的?是否在对象myList上分配了“深层链接”,或者在get函数上分配了诸如“ functor”之类的东西? 我的意思是,如果我使用a,是否每次都会再次调用get函数?
我问的原因:如果我在多线程的情况下使用它,并且在get和set函数中对对象进行了一些锁定,则我不想绕过锁定。因此,如果我先在a上分配myList然后使用它,它将不再被锁定?我说的对吗?
答案 0 :(得分:4)
但是在
a
上真正分配了什么?
a
的类型为List<int>
,列表是引用类型,因此变量包含对列表的引用。 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]);
如果a
再次获取该属性,则该属性应为100。否则,该属性应为10。对将要发生的情况进行预测,然后尝试一下,看看您是否正确。
如果我在多线程的情况下使用此方法,并且在get和set函数中对对象进行了一些锁定,则我不想绕过锁定。因此,如果我先将
MyList
分配给a
,然后再使用它,它将不再被锁定吗?我说的对吗?
是的。我将借此机会指出,创建公开接口以公开必须锁定的对象是非常糟糕的编程习惯。更好的选择是:
答案 1 :(得分:0)
属性最好命名为List<int> getValue()
和setValue(List<int> value)
函数对。有一些次要属性:
但是总的来说,这就是他们的全部。
自动实现属性与手动属性相同,只是后备字段没有名称(您可以在代码中使用),因此偶然访问后备字段的机会为零。
具有属性的最重要规则之一是不要编写Backing字段,尤其是在类代码中。只是较低的外壳它不起作用。我记不清我编码的频率有多快,大写字母没有粘住。为了可靠的命名,请在背景字段后面加上下划线。 _MyList
和MyList
很难混淆。 MyList
和myList
很容易混淆。
答案 2 :(得分:0)
将myInstance.MyList
分配给a
时,调用MyList
get属性,它将引用myList
复制到a
中。如果您随后使用a
,则将直接使用私有myList
所引用的列表。如果您实际调用它,您将仅通过get属性。
这基本上失去了myList
的私密性。如果要强制调用者使用诸如锁定之类的函数,则必须为要允许的操作编写函数,例如添加到列表中,而不会将实际的列表暴露给调用者。
对于线程安全操作,无需在C#中执行此操作-您应使用Concurrent Collections,以免费实现这些操作。