我已经开始构建一个C#应用程序了,我的眼中有点刺痛:
我的大多数课程都有很多属性,例如:
private IList<Address> _addresses;
private IList<Phone> _phones;
public virtual IList<Address> Addresses
{
get
{
if (_addresses == null)
_addresses = new List<Address>();
return _addresses;
}
set { _addresses = value; }
}
public virtual IList<Phone> Phones
{
get
{
if (_phones == null)
_phones = new List<Phone>();
return _phones;
}
set { _phones = value; }
}
我想知道,有没有办法在一个地方定义这种行为(具体来说,默认的getter),并重用它?我应该以某种方式延长IList
吗?
就像我可以使用
一样public virtual string Temp { get; set; }
而不是:
private string _temp;
public virtual string Temp
{
get { return _temp; }
set { _temp = value; }
}
答案 0 :(得分:4)
您可以使用List<T>
完全使用string
。您可能遇到的问题是,在两种情况下,属性都是null
,直到您为getter分配一个值,即if
语句。
您将无法通过扩展IList
来解决此问题。
您可以初始化支持字段:
private IList<Thing> _things = new List<Thing>();
在C#的下一个版本中,您实际上可以以相同的方式初始化自动属性。语法需要一点时间习惯:
public IList<Thing> Things { get; set; } = new List<Thing>();
您还可以在getter中使用此语法在第一次调用getter时初始化集合:
get { return _things ?? (_things = new List<Thing()); }
最后,您可以在构造函数中将值分配给自动属性。这可能更容易出错,因为声明和赋值没有可见的连接。
答案 1 :(得分:3)
目前最短的方法是:
public static List<int> _list;
public static List<int> List
{
get { return _list ?? (_list = new List<int>()); }
set { _list = value; }
}
如果它是_list
,则初始化null
,否则返回_list
字段。
答案 2 :(得分:2)
您可以初始化字段:
private IList<Address> _addresses = new List<Address>();
private IList<Phone> _phones= new List<Phone>();
或者在构造函数中设置属性:
//constructor
public MyClass()
{
Addresses = new List<Address>();
Phones = new List<Phone>();
}
但这些与您的代码完全相同。在您的情况下,如果从未调用过属性,则永远不会初始化它们。
答案 3 :(得分:2)
在不幸的C#6中,您可以执行以下操作:
public virtual IList<Address> Addresses { get; set; } = new List<Address>();
public virtual IList<Phone> Phones { get; set; } = new List<Phone>();
现在你可以使用自动属性和默认的构造来缩短它:
public virtual IList<Address> Addresses { get; set; };
public virtual IList<Phone> Phones { get; set; };
public CLASS()
{
Addresses = new List<Address>();
Phones = new List<Phone>()
}
注意:两种解决方案都会立即初始化列表,而不是首次访问。如果不需要,我想你可以使用PostSharp来做这些事情。
我应该以某种方式扩展IList吗?
这对于&#34;非初始化字段&#34;的情况没有帮助。你的自定义实现甚至不会#34;还有#34;。
答案 4 :(得分:1)
我会在等待C#6时创建一个静态辅助函数,这就是它在我选择的MVVM框架中的完成方式。我认为这是一个相当普遍的实现,可以添加更多的重载来处理极端情况。
public static class PropertyHelper
{
public static T Get<T, U>(ref T backingField, U initialValue = null)
where T : class
where U : class, T, new()
{
initialValue = initialValue ?? new U();
return backingField ?? (backingField = initialValue);
}
}
public class MyClass
{
private IList<int> myVar;
public IList<int> MyProperty
{
get { return PropertyHelper.Get<IList<int>, List<int>>(ref myVar); }
set { myVar = value; }
}
private IList<int> myVar2;
public IList<int> MyProperty2
{
get { return PropertyHelper.Get(ref myVar2, new List<int>()); }
set { myVar2 = value; }
}
}