0

我有一个名为 Fruits 的属性,其中包含一个逗号分隔的字符串,格式为“apples,bananases,peaches”

我想在同一个类中创建一个列表,这使得 Fruits 属性更易于操作。访问器将不起作用,因为列表不支持它们或看起来如此。

基本上我想要一个名为 FruitList 的属性,它根据 Fruits 属性自动填充,当添加项目或操作 FruitList 时,它应该自动填充 fruits 属性。

我需要实体框架的水果属性。

4

3 回答 3

3

您可以反转逻辑:

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通过Fruits查看FruitsList. 您提到您需要Fruits作为string实体框架的属性,但 EF 并不关心它是否由string字段支持。

于 2013-02-20T13:05:02.193 回答
1

唯一现实的方法是使用可以观察更改的集合,并处理更改时引发的事件,并更新属性。

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

看到这里的概念有效,值得注意的是,上述实现充满了一点危险。ObservableCollection每次您在其上调用访问器时,它都会创建一个新的get,这可能会产生一些意想不到的后果。

例如,如果您在我原来的之前添加以下行Console.WriteLine

Console.WriteLine("{0}", obj.FruitList == list);

它输出false的结果可能看起来很奇怪,就像您可能(并且理论上应该)期望的那样list,并obj.FruitList指向同一个列表。

您可以通过将实现更改为仅创建 1ObservableCollection并始终从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;
        }
    }
}

现在世界一切都好起来了!

于 2013-02-20T12:53:57.703 回答
0

这是您可以做的,为您的逗号分隔列表创建一个代理:

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); }
    }
}

当我说 setter 很危险时,我只是说如果你改变了数组的一个元素, Fruit 就不会被更新。仅当您推送新数组时才会更新。如果您需要该行为,请考虑使用 ObservableCollection 实现它

于 2013-02-20T12:54:19.857 回答