Метод цепочки расширений общего списка - PullRequest
1 голос
/ 26 января 2009

У меня есть список «сложного» типа - объект с несколькими строковыми свойствами. Сам список является свойством другого объекта и содержит объекты различных типов, как показано в этой сокращенной структуре классов:

Customer {
   public List<Characteristic> Characteristics;
   .
   .
   .
}

Characteristic {
   public string CharacteristicType;
   public string CharacteristicValue;
}

Я бы хотел иметь возможность собрать Список значений данного типа Характеристик для текущего Клиента, что я могу сделать в двухэтапный процесс следующим образом:

List<Characteristic> interestCharacteristics = customer.Characteristics.FindAll(
   delegate (Characteristic interest) {
      return interest.CharacteristicType == "Interest";
   }
);

List<string> interests = interestCharacteristics.ConvertAll<string>(
   delegate (Characteristic interest) {
      return interest.CharacteristicValue;
   }
);

Это прекрасно работает, но кажется, что далеко. Я уверен, что мне не хватает более простого способа попасть в этот список, либо путем объединения методов FindAll () и Convert (), либо чего-то еще, что я пропускаю полностью.

Что касается фона, я работаю в .Net 2.0, поэтому я ограничен обобщениями .Net 2, а класс Characteristic является внешней зависимостью - я не могу изменить его структуру, чтобы упростить ее, и есть другие важные для класса аспекты, просто не связанные с этой проблемой.

Любые указатели или дополнительные чтения приветствуются.

Ответы [ 3 ]

1 голос
/ 27 января 2009

Я бы сделал некоторые работы вручную. Делая сначала FindAll, а затем Convert, вы дважды просматриваете свою коллекцию. Это не кажется необходимым. Если все, что вы хотите в конце дня, это List of CharacteristicValue, то просто переберите исходную коллекцию и добавьте CharacteristicValue в список каждого, который соответствует вашим критериям. Примерно так:

     Predicate<Characteristic> criteria = delegate (Characteristic interest) 
     {
          return interest.CharacteristicType == "Interest";
     };
     List<string> myList = new List<string>();
     foreach(Characteristic c in customer.Characteristics)
     {
        if(criteria(c))
        {
            myList.Add(c.CharacteristicValue);
        }
     }
1 голос
/ 27 января 2009

Вот реализация генератора

public static IEnumerable<string> GetInterests(Customer customer)
{
    foreach (Characteristic c in customer.Characteristics)
    {
        if (c.CharacteristicType == "Interest")
            yield return c.CharacteristicValue;
    }
}

К сожалению, методы расширения 3.5 и лямбда-выражения отсутствуют в зависимости от ваших требований, но для справки вот как это сделать:

customer.Characteristics
    .Where(c => c.CharacteristicType == "Interest")
    .Select(c => c. CharacteristicValue);
0 голосов
/ 26 января 2009

Почему бы не создать Dictionary<string, List<string>>, чтобы вы могли добавить «Проценты» в качестве ключа и список значений в качестве значения. Например:

Customer {
   public Dictionary<string, List<string>> Characteristics;
   .
   .
   .
}

...

Characteristics.Add("Interest", new List<string>());
Characteristics["Interest"].Add("Post questions on StackOverflow");
Characteristics["Interest"].Add("Answer questions on StackOverflow");
..

List<Characteristic> interestCharacteristics = Characteristics["Interest"];

Кроме того, если вы хотите, вы можете ограничить свои характеристики списком возможных значений, сделав его перечислением, а затем использовать его в качестве типа данных ключа вашего словаря:

public enum CharacteristicType
{
   Interest,
   Job,
   ThingsYouHate
//...etc
}

затем объявите ваш словарь как:

public Dictionary<CharacteristicType, List<string>> Characteristics;
..
Characteristics.Add(CharacteristicType.Interest, new List<string>());
Characteristics[CharacteristicType.Interest].Add("Post questions on StackOverflow");
Characteristics[CharacteristicType.Interest].Add("Answer questions on StackOverflow");
...