过滤匿名对象数组

米格尔·莫拉

我有以下方法:

public static Object[] GetCategories() {
  return new [] {
    new { Id = 1, Name = "A" }, 
    new { Id = 2, Name = "B" },
    new { Id = 2, Name = "BA" },
    new { Id = 2, Name = "BC" }
  }
}

在同一堂课上,我有另一种方法:

public static Object[] GetPosts() {

  var categories = GetCategories() ...

}

在此方法中,我需要获取名称包含字母“A”的类别。

如果 GetCategories 正在返回并且必须返回一个 Object 数组,我该怎么做。

如果 GetCategories 正在返回并且必须返回一个 Object 数组,我该怎么做。

你不能。Object缺乏必要的类型信息,因此您必须求助于反射或强制转换为显式(非匿名)类型。

由于我们不能var在 C# 的方法签名中使用隐式类型 ( )(与在 C++ 中可以使用的不同auto),我们必须使用值元组(C# 7.2 功能)或手动定义您的对象类型。

C# 7.2 值元组:

public static (Int32 id, String name)[] GetCategories()
{
    return new[]
    {
        ( 1, "A" ),
        ( 2, "BA" ),
        ( 3, "BAC" ),
    };
}

手动类型:

public class /* or struct */ Category
{
    public Category( Int32 id, String name )
    {
        this.Id = id;
        this.Name = name;
    }

    public Int32 Id { get; }
    public String Name { get; }
}

public static Category[] GetCategories()
{
    return new[]
    {
        new Category( 1, "A" ),
        new Category( 2, "BA" ),
        new Category( 3, "BAC" ),
    };
}

你说方法的签名必须 return Object[],但是如果我们返回一个值元组或自定义类型,那么我们仍然可以转换为它,尽管没有编译时类型安全:

public Object[] GetCategories()
{
    return new[]
    {
        new Category( 1, "A" ),
        new Category( 2, "BA" ),
        new Category( 3, "BAC" ),
    };
}

IEnumerable DoSomething()
{
    return this.GetCategories()
        .Cast<Category>()
        .Where( c => c.Name.Contains("A") )
}

或者:

public Object[] GetCategories()
{
    return new (Int32 id, String name)[]
    {
        new ( 1, "A" ),
        new ( 2, "BA" ),
        new ( 3, "BAC" ),
    };
}

IEnumerable DoSomething()
{
    return this.GetCategories()
        .Cast<(Int32 id, String name)>()
        .Where( c => c.Name.Contains("A") )
}

在我看来,无论如何我们都应该更喜欢值元组而不是匿名类型,它们比 C# 的匿名类型有很多优势:

  • 您可以在方法签名中将它们用作返回类型或参数类型。
  • 它们是不可变的。
  • 它们是值类型(不是堆分配的对象),可以避免不必要的分配。
  • 只要您使用匿名类型,就可以使用它们。

唯一的缺点是让自己面临一场关于值元组成员应该是PascalCase还是的小人国战争camelCase

顺便说一句,如果您的数据是不可变的,那么您应该返回一个static readonly IReadOnlyList[]而不是,return new[]...以避免在每次调用时进行无关的不必要的堆分配,并防止静态状态发生不必要的突变:

private static readonly IReadOnlyList[] _categories = new[]
{
    ...
};

public static IReadOnlyList[] GetCategories() => _categories;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章