列表上的属性访问器<;T>;在里面NET
本文关键字:gt 在里面 NET lt 属性 访问 列表 | 更新日期: 2023-09-27 18:00:19
我有一个名为Fruits的属性,它包含一个逗号分隔的字符串,格式为"apples,bananases,peaks"
我想在同一个类中创建一个列表,使Fruits属性更易于操作。访问器无法工作,因为列表上不支持它们,或者看起来是这样。
基本上,我想要一个名为FruitList的属性,它基于Fruits属性自动填充,当添加项目或操作FruitList时,它应该自动填充Fruits属性。
我需要实体的水果属性框架。
您可以反转逻辑:
List<string> fruitsList = new List<string>();
public List<string> FruitsList
{
get
{
return fruitsList;
}
}
public string Fruits
{
get
{
return string.Join(',', fruitsList);
}
set
{
// Incomplete, does not handle null
FruitsList.Clear();
FruitsList.AddRange(value.Split(','));
}
}
如果Fruits
是通过查看FruitsList
确定的,则不必担心更新Fruits
。您提到需要Fruits
作为Entity Framework的string
属性,但EF并不关心它是否由string
字段支持。
实现这一点的唯一现实方法是使用一个可以观察更改的集合,处理更改时引发的事件,并更新属性。
像ObservableCollection<T>
这样的东西很合适。
示例:
public class MyObject
{
public string Fruits{get;set;}
public IList<string> FruitList
{
get
{
var list = new ObservableCollection<string>(Fruits.Split(','));
list.CollectionChanged += (s,ea) => {
var items = (IList<string>)s;
Fruits = String.Join(",",items);
};
return list;
}
}
}
用法:
var obj= new MyObject(){ Fruits="Apple,Banana,Orange" };
var list = obj.FruitList;
list.Add("Satsuma");
list.Add("Grapes");
list.Remove("Apple");
Console.WriteLine(obj.Fruits); // Output: Banana,Orange,Satsuma,Grapes
现场示例:http://rextester.com/KCT33825
看到概念在这里起作用后,值得注意的是,上面的实现有点危险。每次调用get
访问器时,它都会创建一个新的ObservableCollection
,这可能会产生一些意外的后果。
例如,如果您在我原来的Console.WriteLine
:之前添加以下行
Console.WriteLine("{0}", obj.FruitList == list);
它输出false
,这可能看起来很奇怪,因为您可能(理论上应该)期望list
和obj.FruitList
指向同一列表。
您可以通过将实现更改为只创建1个ObservableCollection
,并始终从get
访问器返回该实现来绕过此问题:
public class MyObject
{
private string fruits;
private ObservableCollection<string> fruitList;
public string Fruits
{
get{ return this.fruits; }
set
{
this.fruits = value;
this.fruitList = CreateFruitList();
}
}
private ObservableCollection<string> CreateFruitList()
{
var list = new ObservableCollection<string>(this.fruits.Split(','));
list.CollectionChanged += (s,ea) => {
var items = (IList<string>)s;
this.fruits = String.Join(",",items);
};
return list;
}
public IList<string> FruitList
{
get
{
return fruitList;
}
}
}
现在世界又好了!
以下是您可以做的,为逗号分隔的列表创建一个代理:
public class MyClass
{
public string Fruits {get;set;}
public string [] FruitList {
get { return Fruits.Split(new [] {','}); }
//warning, the setter is dangerous
set { Fruits = string.Join(',', value); }
}
}
当我说二传手很危险时,我只是说如果你改变了阵列的一个元素,果实就不会更新。只有当你推送一个新数组时,它才会更新。如果您需要该行为,请考虑使用ObservableCollection 来实现它