1

考虑以下:

public interface ITree<X>
{
  ...
  ITree<X> Union(ITree<X> other);
  ...
}

这个想法是我要实现几种类型的树。但是,该Union()方法仅在您尝试合并两个相同类型的树时才有效。但是,上面的类型签名并没有强制执行此限制。

所以,我的问题是:如何编写类型签名以Union()使other参数必须具有与 相同的类型this

(显然,如果类型不匹配,我可以进行动态运行时测试并抛出异常。但我更愿意在编译时检查它是否可以完成......)

4

4 回答 4

2

没有一种特别干净的方式来表达这一点,这是使用接口的结果,因为没有办法知道ITree<X>. 最好的方法可能是创建另一个类/接口来约束具体的树类型并执行您需要的操作:

public interface ITreeUnion<T, X> where T : ITree<X>
{
    T Union(T left, T right);
}

然后,您必须将此接口类型的实例传递到您需要执行所需操作的位置。

如果你真的需要Union进入界面,你可以使用循环模板:

public interface ITree<T, X> where T : ITree<T, X>
{
    T Union(T other);
}

public class RedBlackTree<T> : ITree<RedBlackTree<T>, T>
{
    public RedBlackTree<T> Union(RedBlackTree<T> other)
    {
    }
}
于 2013-03-14T19:27:32.617 回答
1

根据您的要求,您需要一个Union().

  • 界面

    public partial interface ITree<X> {
        T Union<T>(T other) where T: ITree<X>;
    }
    
  • 样本类

    public partial class TreeOfObject: ITree<object> {
        public T Union<T>(T other) where T: ITree<object> {
            return default(T); // sample only; shuold be implemented yourself
        }
    }
    
    public partial class TreeOfInt: ITree<int> {
        public T Union<T>(T other) where T: ITree<int> {
            return default(T); // sample only; shuold be implemented yourself
        }
    }
    
  • 测试

    public static partial class TestClass {
        public static void TestMethod() {
            var x=new TreeOfObject();
            var y=new TreeOfInt();
    
            var xx=x.Union(x);
            var yy=y.Union(y);
    
            var xy=x.Union(y); // won't compile
            var yx=y.Union(x); // won't compile
        }
    }
    
于 2013-03-14T21:21:19.683 回答
0

那你为什么需要接口呢?只需Replace在树的每个实现上实现一个方法:

public class RedBlackTree<T> {
    public RedBlackTree<T> Union(RedBlackTree<T> other) { ... }
}

public class SplayTree<T> {
    public SplayTree<T> Union(SplayTree<T> other) { ... }
}

由于您在处理 的每个实现时都在寻找编译时安全性ITree,所以我认为您只需要处理具体类型。当然,ITree<T>如果需要,您可以使用其他方法。

于 2013-03-14T19:27:25.487 回答
0

不知何故,以下实际上编译

public interface ITree<TSelf, TItem> where TSelf : ITree<TSelf, TItem>
{
    TSelf Union(TSelf other);
    // ...
}

public class AvlTree<TItem> : ITree<AvlTree<TItem>, TItem> {
    public AvlTree<TItem> Union(AvlTree<TItem> other) {
        return other;
    }
}

当然它不是特别有用,因为那时您必须将变量声明为ITree<AvlTree>,此时您最好不要使用该接口。对于 C# 泛型,必须在某个时候知道泛型类型参数的值才能具体化泛型类型。

于 2013-03-14T19:30:05.623 回答