我有以下方法:
public TResult Get<TGenericType, TResult>()
where TGenericType : SomeGenericType<TResult>
where TResult : IConvertible {
//...code that uses TGenericType...
//...code that sets someValue...
return (TResult) someValue;
}
现在,此方法的用户必须像这样使用它:
//Notice the duplicate int type specification
int number = Get<SomeGenericType<int>, int>();
为什么我必须在方法定义中指定TResult?编译器已经知道了TResult,因为我在TGenericType中指定了它。理想情况下(如果C#编译器更聪明一点),我的方法看起来像这样:
public TResult Get<TGenericType>()
where TGenericType : SomeGenericType<TResult>
where TResult : IConvertible {
//...code that uses TGenericType...
//...code that sets someValue...
return (TResult) someValue;
}
因此用户可以像这样简单地使用它:
//Much cleaner
int number = Get<SomeGenericType<int>>();
有办法做我想做的事吗?
答案 0 :(得分:8)
C#规范不允许推断一半的类型参数。你应该让编译器推断出所有的类型参数(这并不总是适用的,就像你的情况一样)或者手动指定所有这些参数。
更新(回复评论):虽然我不是在C#团队中对你的问题给出一个绝对的答案,但我猜测重载决议的复杂性(已经在意 - 吹嘘;你知道,如果你读过C#规范的那一部分,如果他们想要推断一半的类型被推断而一半不能(特别是考虑到你可以仅通过泛型参数的数量来重载方法的事实)会显着增加。
答案 1 :(得分:1)
这取决于......
如果您只是使用SomeGenericType<TResult>
,则可以执行以下操作:
public TResult Get<TResult>() where TResult : IConvertible {
SomeGenericType<TResult> myInstance = ...
//...code that sets someValue...
return (TResult) someValue;
}
在这种情况下,没有必要将第一种类型放在那里。由于您的示例未明确传递SomeGenericType<TResult>
作为参数,因此它表明这是可能的。
否则,您需要完全指定所有通用参数。不幸的是,这就是它在C#中的方式。