c# - 未显式传递时通用类型的值?

标签 c# generics

在审查 github 上的一些代码时,我遇到了这种模式:

using System.Linq.Expressions;

public T SomeGenericMethod<TValue>(Expression<Func<T, TValue>> myExpr){
    // ...
}

这是代码中唯一相关的部分。 TValue实际上从未在方法主体中使用过,它仅在Func<,>中使用。类型。

它的使用如下所示:

myObj.SomeGenericMethod(x => x.SomeProperty)

请注意,调用 SomeGenericMethod 时不会传递泛型。 。我本来期望编译器需要类似的东西:

myObj.SomeGenericMethod<SomeTValue>(x => x.SomeProperty)

但事实并非如此。

所以我的问题是,TValue 是什么?当没有任何内容作为类型显式传递给泛型方法调用时?

最佳答案

在本例中,它是typeof(SomeProperty)。 C# 编译器会自动发现它。来自 https://msdn.microsoft.com/en-us/library/twcad0zb.aspx

You can also omit the type argument and the compiler will infer it.

The compiler can infer the type parameters based on the method arguments you pass in; it cannot infer the type parameters only from a constraint or return value. Therefore type inference does not work with methods that have no parameters. Type inference occurs at compile time before the compiler tries to resolve overloaded method signatures. The compiler applies type inference logic to all generic methods that share the same name. In the overload resolution step, the compiler includes only those generic methods on which type inference succeeded.

请注意,您可能会认为这种用法很奇怪,但是当您使用 LINQ 时,您会正常这样做。使用 Line 你可以写:

var coll = new[] { new { Foo = 1, Bar = 2 } };
var enu = coll.Select(x => x.Foo).ToList();

您没有在 Select 中的任何地方明确说明 Foo 的类型。编译器推断它是一个int

Select 的签名是:

public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)

因此 Foo 的类型是 TResult

如果没有这种类型推断,匿名对象几乎毫无用处,因为你不能:

class MyClass 
{ 
    public int Foo { get; set; } 
    public int Bar { get; set; } 
}

var coll = new[] { new MyClass { Foo = 1, Bar = 2 } };
var enu = coll.Select<MyClass, ???>(x => new { Bar = x.Foo }).ToList();

你会在???中放入什么?根据匿名对象的定义,您无法显式命名它们:-)

关于c# - 未显式传递时通用类型的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29750060/

相关文章:

c# - 从 C++ 调用 C# dll

C# 将 Foo<Bar> 转换为 Foo<object>

generics - 如何在 Scrap Your Boilerplate (SYB) 中使用 `local` 和 `Reader` monad?

generics - 非泛型结构可以在 Rust 中实现泛型函数吗?

c# - 系统找不到使用 X509Certificate2 指定的文件来连接 Azure 服务器中的 Google OAuth2.0

c# - 首先从 Entity Framework 数据库中的查询中获取数据

c# - 如果在例程中多次访问对象的属性,创建变量是最佳做法吗?

c# - 自动重新连接异步套接字客户端

android - Kotlin 泛型抽象类

java - 从泛型创建类对象