我有这个方法:
library(data.table)
df = data.table(
In=as.Date('2008-12-18') + cumsum(c(0,4,7,7,8,1,5)),
Out=as.Date('2008-12-19') + cumsum(c(0,4,10,3,8,1,5)),
tag=1)
toMerge = df[, .(In=Out+1, Out=shift(In-1, type='lead'), tag=0)][In <= Out]
> merge(df, toMerge, all=T)
# In Out tag
# 1: 2008-12-18 2008-12-19 1
# 2: 2008-12-20 2008-12-21 0
# 3: 2008-12-22 2008-12-23 1
# 4: 2008-12-24 2008-12-28 0
# 5: 2008-12-29 2009-01-02 1
# 6: 2009-01-03 2009-01-04 0
# ...
现在我希望此方法也出现在public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func)
where TResult : AnotherType
中。所以我写了这个,显然没有编译:
IEnumerable<AnotherType>
我收到编译错误:
已声明相同签名的成员
我读了Member with the same signature already defined with different type constraints,它使用另一种返回类型来处理成员。但是在我的例子中,我没有区分方法return-type,而是在它的param-list上,首先是public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func)
where TResult : IEnumerable<AnotherType>
,第二个是Func<MyType, TResult>
。但是编译器无法处理这个问题。
还有另一种方法,而不是第二个例子的另一个方法名称?
答案 0 :(得分:5)
确实,两个方法重载不允许仅仅由通用约束区分开来。
在你的情况下,我想知道你是否需要TResult
(正如Alfie Goodacre所评论的那样)因为IEnumerable<out T>
中的T
是协变的,Func<in T1, out TResult>
中的协变是TResult
{1}}。
所以试试:
public IEnumerable<MyType> DoSomething(Func<MyType, AnotherType> func)
和
public IEnumerable<MyType> DoSomething(Func<MyType, IEnumerable<AnotherType>> func)
由于上面提到的协方差,在调用上述重载时使用比AnotherType
派生的类更好。
另一种选择:
public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, TResult> func)
where TResult : AnotherType
和
public IEnumerable<MyType> DoSomething<TResult>(Func<MyType, IEnumerable<TResult>> func)
where TResult : AnotherType
在这种替代方法中,签名不同,并且两个过载中的约束相同。即使AnotherType
是interface
而TResult
是实现接口的struct
(值类型),这也可以起作用,这是协方差(out T
和out TResult
)不起作用。