最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - .NET Core 8 - check value of property of type Object in linq - Stack Overflow

programmeradmin3浏览0评论

I have a method that receives a list of Foo object. a Foo object contains a property that is a Dictionary<string,object>. (where object will be a primitive type: string, int, double...) I am trying to get the Foo objects in the list whose dictionary contains an element with a given value.

What I tried:

public List<Foo> FindFoos(List<Foo> foos, string itemKey, object itemValue) {
    List<Foo> found = foos.Where(f => f.TheDict[itemKey] == itemValue).ToList();
    return found;
}

and then call it with:

  var a = FindFoos(foos, "name", "Something");
  var b = FindFoos(foos, "age", 45);

I have a method that receives a list of Foo object. a Foo object contains a property that is a Dictionary<string,object>. (where object will be a primitive type: string, int, double...) I am trying to get the Foo objects in the list whose dictionary contains an element with a given value.

What I tried:

public List<Foo> FindFoos(List<Foo> foos, string itemKey, object itemValue) {
    List<Foo> found = foos.Where(f => f.TheDict[itemKey] == itemValue).ToList();
    return found;
}

and then call it with:

  var a = FindFoos(foos, "name", "Something");
  var b = FindFoos(foos, "age", 45);
Share Improve this question asked Mar 11 at 16:24 patsy2kpatsy2k 6113 silver badges11 bronze badges 2
  • 3 So what's the problem? – Blindy Commented Mar 11 at 16:56
  • 1 Please edit the question to include a minimal reproducible example rather than snippets. – Jon Skeet Commented Mar 11 at 17:02
Add a comment  | 

3 Answers 3

Reset to default 1

Maybe this:

public List<Foo> FindFoos(List<Foo> foos, string itemKey, object itemValue) 
{
    List<Foo> found = foos
    .Where(f => f.TheDict.TryGetValue(itemKey, out var someValue)
        && someValue.Equals(itemValue))
    .ToList();
    return found;
}

== does a reference equality on object. Use Object.Equals instead. This will use the overridden implementations of the specific object types.

public List<Foo> FindFoos(List<Foo> foos, string itemKey, object itemValue) {
    return foos
        .Where(f => f.TheDict[itemKey].Equals(itemValue))
        .ToList();
}

This will work well if only valid item keys are provided. If you have keys that are not in the dictionary, use Ivan Petrov's approach with TryGetValue.

I wanted to build on Ivan's excellent answer ▲ by suggesting that you write this as an extension method so that it can be used and chained just like any other Linq-Like expression.


Extension

public static class Extensions
{
    public static List<Foo> FindFoos(this List<Foo> foos, string itemKey, object itemValue) =>
        (string.IsNullOrWhiteSpace(itemKey)
        ? new List<Foo>()
        : foos
            .Where(_ => _.TheDict
                         .TryGetValue(itemKey, out var someValue) && 
                        someValue.Equals(itemValue)))
            .ToList();
}

Usage

// List<Foo> superset is some initialized list of Foo.
List<Foo> subset = superset.FindFoos("Occupation", "Engineer"))

Minimal example on Console App


Console.Title = "Test Extension";

List<Foo> sourcelist =
    Enumerable.Range(0, 4)
    .Select(n => new Foo {Id = n}.WithTestData())
    .ToList();

foreach (var foo in sourcelist.FindFoos("Occupation", "Engineer"))
{
    Console.WriteLine($"Match found in Foo #{foo.Id}");
}
Console.ReadKey();
return;

public class Foo
{
    public int Id { get; init; }
    public Dictionary<string, object> TheDict { get; } = new();
    public override string ToString() => $"{Id}";
}

public static class Extensions
{
    public static List<Foo> FindFoos(this List<Foo> foos, string itemKey, object itemValue) =>
        (string.IsNullOrWhiteSpace(itemKey)
        ? new List<Foo>()
        : foos
            .Where(_ => _.TheDict
                         .TryGetValue(itemKey, out var someValue) && 
                        someValue.Equals(itemValue)))
            .ToList();

    public static Foo WithTestData(this Foo @this)
    {
        switch (@this.Id)
        {
            case 0:
                @this.TheDict.Add("Name", "Alice");
                @this.TheDict.Add("Age", 25);
                @this.TheDict.Add("Occupation", "Engineer");
                break;
            case 1:
                @this.TheDict.Add("Name", "Bob");
                @this.TheDict.Add("Age", 30);
                @this.TheDict.Add("Occupation", "Engineer"); // Same occupation as Alice
                break;
            case 2:
                @this.TheDict.Add("Name", "Charlie");
                @this.TheDict.Add("Age", 35);
                @this.TheDict.Add("Occupation", "Artist");
                break;
            case 3:
                @this.TheDict.Add("Name", "Diana");
                @this.TheDict.Add("Age", 28);
                @this.TheDict.Add("Occupation", "Chef");
                break;
        }
        return @this;
    }
}

发布评论

评论列表(0)

  1. 暂无评论