如果在C#中可以使用以下内容,我只是在徘徊。
假设我有一个类似List的界面,要求操作reverse
。即:
public interface ReversableList<T> {
// Return a copy of this list but reversed
ReversableList<T> Reverse();
// We still need to return the contained type sometimes
T Get(int index)
}
然而,现在当我去实现那个界面时:
public class ListImplementation<T> : ReversableList<T>
ReversableList<T> Reverse();
}
我仍然被迫使用界面ReversableList
。因此,即使用户直接实例化我的ListImplementation
,他们在调用ReversableList
方法时仍然被迫处理Reverse
:
var concreteList = new ListImplementation<String>();
ReversableList<T> reversed = concreteList.Reverse();
而我的想法是Reverse()
的{{1}}将是另一个ListImplementation
,就像这样:
ListImplementation
同时仍然实现足够通用的界面。
如果这令人困惑,请告诉我,我会澄清/添加任何必要的细节或更正。谢谢!
以下是对我感兴趣的原因的解释。
我通过var concreteList = new ListImplementation<String>();
ListImplementation<String> reversed = concreteList.Reverse();
(具体类型)scala's collections中的reversed
函数,通过它继承的所有接口(特征)。
我发现的非常好奇。
原始的List
方法是在GenSeqLike
trait上抽象定义的。
reverse
然后,在trait SeqLike中定义具体,扩展trait GenSeqLike[+A, +Repr] ...
def reverse: Repr // <--- NO BODY, means abstract
特征:
GenSeqLike
然后,有趣的是,接下来的两个特征是:
trait SeqLike[+A, +Repr] extends GenSeqLike[A, Repr]
def reverse: Repr
//iterates through this seqence
// and reverses
for (x <- this)
//...etc
都获得trait Seq[+A] extends SeqLike[A, Seq[A]] //<-- NOTE here is the type for "Repr"
//no mention of reverse
trait LinearSeq[+A] extends Seq[A] with SeqLike[A, Seq[A]] //<-- NOTE type again
// no mention of reverse
函数的“免费”版本,但它们都根据各自的“接口”(特征)工作。因此reverse
上的reverse
会返回Seq
。
最后,Seq
具体类实现List
特征并重新定义LinearSeq
方法(出于效率目的,我假设)。
reverse
sealed abstract class List[+A] extends LinearSeq[A]
with LinearSeqOptimized[A, List[A]]
override def reverse: List[A] = {
//faster impl without foreach iteration
...
}
只是另一个特征的“链”,一直到LinearSeqOptimized
。
所以你可以看到,如何使用通用“接口”来指定一些“行为”,中间“接口”如何提供某种“默认”实现,以及所有子接口和子类型如何获得了该实现的好处,同时保留了返回类型为“自己的”类型。唷。令人困惑,我知道!
答案 0 :(得分:4)
你可以这样做,虽然它可能有点棘手。
将ReversableList
界面更改为:
public interface ReversableList<L, T> where L : ReversableList<L, T>
{
// Return a copy of this list but reversed
L Reverse();
}
现在你实现它:
public class ListImplementation<T> : ReversableList<ListImplementation<T>, T>
{
public ListImplementation<T> Reverse() { /* code */ }
}
答案 1 :(得分:1)
像
这样的东西public interface IReversableList<T> where T : IReversableList<T>
{
// Return a copy of this list but reversed
T Reverse();
}
public class ListImplementation<T> : IReversableList<ListImplementation<T>>
{
public ListImplementation<T> Reverse()
{
return new ListImplementation<T>();
}
}
然后可以将其用作
var concreteList = new ListImplementation<string>();
ListImplementation<string> reversed = concreteList.Reverse();
修改强>
在界面上添加了约束。
答案 2 :(得分:0)
此特殊情况已由可枚举扩展程序处理:Enumerable.Reverse
var list = new List<string>(){"a","b","c"};
list.Reverse();
不是这个问题的答案,但未来可能对搜索者有所帮助!