代码之家  ›  专栏  ›  技术社区  ›  Rodrick Chapman

方法和匿名类型

  •  4
  • Rodrick Chapman  · 技术社区  · 17 年前

    编辑

    假设L是一个列表。这是怎么回事?

    L.Select(s => new { Name = s })
    

    返回类型为IEnumerable<'a>其中'a=new{String Name}

    4 回复  |  直到 15 年前
        1
  •  8
  •   Mark Brackett    17 年前

    该类型实际上是由 来电者 ,因此它在调用函数的范围内-巧妙地避免了“返回”匿名类型的问题。

    这是通过泛型类型推断完成的。签名 Select Select<Tsource, TResult>(IEnumerable<TSource>, Func<TSource, TResult> . 这个 IEnumerable<TSource> 显然,是源代码集合。这个 Func<Tsource, TResult>

    换句话说,为了通过考试 Func<t来源、结果> Select ,您(调用方)必须定义 TResult 选择 不是返回由它定义的匿名类型,而是由您定义的匿名类型。

    TResult ReturnAnonymousType<TResult>(Func<TResult> f) {
       return f();
    }
    
    Console.WriteLine(ReturnAnonymousType(
       () => return new { Text = "Hello World!" } // type defined here, before calling 
    );
    
        2
  •  8
  •   Jon Skeet    17 年前

    这是泛型方法类型参数的正常类型推断。例如:

    List<string> x = new List<string>();
    
    // The compiler converts this:
    x.Select(y => y.Length);
    
    // Into this, using type inference:
    Enumerable.Select<string, int>(x, y => y.Length);
    

    如果 x 是某个匿名类型的列表,或者lambda表达式的推断返回类型是匿名类型。不要忘记,即使不能显式声明使用匿名类型的变量的类型,它仍然可以

        3
  •  5
  •   Marc Gravell    17 年前

    这里您只需要任何通用方法:

    public List<T> Foo<T>(T template) { // doesn't actually use "template"
        return new List<T>();  // just an example
    }
    

    var list = Foo(new {Bar=1});
    

    编译器提供 <T> 通过泛型类型推断。

    有点厚颜无耻,但您甚至可以不创建anon类型的实例:

    public List<T> Foo<T>(Func<T> func) { // doesn't actually use "func"
        return new List<T>(); // just an example
    }
    
    var list = Foo(() => new {Bar = 1});
    

        4
  •  1
  •   Guvante    17 年前

    Select的返回类型是泛型的,它是从大多数情况下提供的lambda推断出来的。

    例如:

    List<int> list = new List<int<();
    
    var val = list.Select(x => new {value = x, mod = x % 10});
    

    select的返回值基于我定义的匿名类型,并从lambda外推到委托和select函数。本例中的Select函数不知道或不关心特定的匿名类型,因为从其角度来看,它是泛型类型。