允许实现类将自己用作类型

时间:2012-09-28 04:22:22

标签: c#

如果在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

所以你可以看到,如何使用通用“接口”来指定一些“行为”,中间“接口”如何提供某种“默认”实现,以及所有子接口和子类型如何获得了该实现的好处,同时保留了返回类型为“自己的”类型。唷。令人困惑,我知道!

3 个答案:

答案 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();

不是这个问题的答案,但未来可能对搜索者有所帮助!