Упростить и объединить оператор LINQ - PullRequest
0 голосов
/ 24 октября 2018

В настоящее время я работаю над приложением .NET Framework 4.7.2.Я написал оператор LINQ для извлечения значения из keyValuePair с заданной структурой.Значение имеет тип объекта и может иметь значение true, false или «0».

keyValuePair содержит Dictionary<string, object> и выглядит примерно так:

enter image description here

  • Ключ: значение "IsFruit": true
  • Ключ: "IsVegetable" Значение: false
  • Ключ: "IsMeat" Значение: "0"

Я хочу выбрать только логическое значение.Мой запрос LINQ для получения значения выглядит следующим образом:

var val = fruitOrVegetable
    .Where(pair => pair.Key == "IsFruit")
    .FirstOrDefault().Value;

bool isFruitAtPosition;
bool.TryParse(val.ToString(), out isFruitAtPosition);

На самом деле мой код работает нормально, просто я не слишком доволен этим и думаю, что, возможно, существует способ слияния /объединить эти строки в 1 оператор или что-то в этом роде.

У вас есть идеи, как улучшить мой запрос?

Ответы [ 5 ]

0 голосов
/ 24 октября 2018

Вот хороший метод расширения, который вы можете использовать, он универсален и его можно использовать для других типов, кроме bool / bool?:

public class Program
{

 public static void Main()
 {
    var dict = new Dictionary<string, object>{
        {"test1", true},
        {"test2", 2}
    };

    var result = dict.GetDictionaryItemValueOrDefault<bool?>("test1");
    Console.WriteLine(result.ToString());
 }
}

public static class Extensions{
 public static T GetDictionaryItemValueOrDefault<T>(this Dictionary<string, object> dictionary, string key){    
    if(!dictionary.TryGetValue(key, out var result) || !(result is T))
       return default(T);

    return (T)result;
 }  
}
0 голосов
/ 24 октября 2018

Я думаю, вы можете использовать LINQ следующим образом:

var val = fruitOrVegetable.FirstOrDefault(item => item.key == "IsFruit");

, тогда вы можете попытаться привести к bool.

Просто мысль: если значение для Key: "IsMeat" будет0 или 1, вы не можете сделать это типом bool.

0 голосов
/ 24 октября 2018

Это словарь ... вам не нужно LINQ.

Если вам нужно только знать, присутствует ли позиция, то:

bool isFruitAtPosition = fruitOrVegetable.ContainsKey("IsFruit")? fruitOrVegetable["IsFruit"] as bool? ?? false : false;

Или, если вы делаетенужны обе переменные:

var val = fruitOrVegetable.ContainsKey("IsFruit")? fruitOrVegetable["IsFruit"] : new object();
bool isFruitAtPosition = val as bool? ?? false;

Не стесняйтесь делать ремикс на что-то более читаемое в зависимости от вашей базы кода.Если словарь мал, то итерации не будет большой разницы.Если он велик или имеет неявное влияние на производительность, это будет решающий подход к использованию.

0 голосов
/ 24 октября 2018

Мне нравится эта версия.

var isFruitAtPosition = fruitOrVegetable.Any( p => p.Key == "IsFruit" && (bool)p.Value );
0 голосов
/ 24 октября 2018

Вы всегда можете создать свой собственный метод расширения для преобразования объекта в bool или null.

Например,

public static bool? AsBoolOrDefault(this object objectToParse)
{
    return objectToParse is bool ? objectToParse as bool? : null;
}   

и использовать его в своем запросе, например

bool? isFruitAtPosition = fruitOrVegetable.Where(pair => pair.Key == "IsFruit")
                                          .FirstOrDefault().Value.AsBoolOrDefault()

И вы можете использовать его везде, а не только в запросах.

Не по теме

Если использовать доступ к любому свойству или методу после использования FirstOrDefaut и других недействительных выборокметоды, которые вы вызываете для NullReferenceException.Я думаю, что в целом неплохо делать нулевую проверку.

В C # 6 вы можете использовать нулевой условный оператор.

bool? isFruitAtPosition = fruitOrVegetable.Where(pair => pair.Key == "IsFruit")
                                          .FirstOrDefault()?.Value.AsBoolOrDefault()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...