【发布时间】:2020-04-01 17:47:14
【问题描述】:
我正在尝试创建一个方法,它可以接受对象的类型作为类型参数,以及对对象属性之一及其类型的引用。像这样:
service.DoWork<DateTime>(dt => dt.Ticks).
我查看了其他库是如何做这些事情的,最终得到了以下定义:
interface IService
{
void DoWork<TObject, TProperty>(Expression<Func<TObject, TProperty>> propertySelector);
}
理想情况下,用户可以传入对象的类型,然后使用表达式“选择”其每个属性。然后我的方法可以知道选择的表达式,以及它的类型和对象的类型。
service.DoWork<DateTime>(dt => dt.Ticks);
service.DoWork<DateTime>(dt => dt.TimeOfDay);
service.DoWork<DateTime>(dt => dt.Second);
但是,以这种方式调用该方法会导致以下错误:
Using the generic method 'IService.DoWork<TObject, TProperty>(Expression<Func<TObject, TProperty>>)' requires 2 type arguments
如果我指定属性的类型,那么一切正常:
service.DoWork<DateTime, long>(dt => dt.Ticks);
service.DoWork<DateTime, TimeSpan>(dt => dt.TimeOfDay);
service.DoWork<DateTime, int>(dt => dt.Second);
但是,这似乎真的是多余的。编译器可以从我提供的表达式参数中提取类型,据我所知,许多其他库都使用这种类型推断来提供干净的接口(Linq、MOQ、FluentAssertions 等等)
我想我需要以某种方式更改我的方法定义,但我似乎找不到正确的方法来做到这一点。
PS:这里是完整的代码sn-p。
using System;
using System.Linq.Expressions;
namespace GenericTypeInterface
{
class Program
{
static void Main(string[] args)
{
IService service = null;
service.DoWork<DateTime>(dt => dt.Ticks);
service.DoWork<DateTime>(dt => dt.TimeOfDay);
service.DoWork<DateTime>(dt => dt.Second);
}
}
interface IService
{
void DoWork<TObject, TProperty>(Expression<Func<TObject, TProperty>> propertySelector);
}
}
【问题讨论】:
-
类型推断全部或全部无效,您不能指定一个参数而让编译器猜测所有其他参数。如果 DoWork 有两个参数,则指定两个参数或一个都不指定。
标签: c# generics types interface type-inference