繁体   English   中英

C#通用约束:接口

[英]C# generic constraints : Interface

我对某些代码有疑问:

interface IDistance<T> 
{
        double distance();
        double distance(T obj);
}

class Point<T> where T : IDistance<T>  //why do i need this?
{
        T obj;
        public double dist(T val) { return obj.distance(val); 
        public Point(T obj) { this.obj = obj; }
}

class P2D : IDistance<P2D>
{
        public double[] x = new double[2];

        public P2D(double x, double y)
        {
            this.x[0] = x; this.x[1] = y;
        }

        public double distance()
        {
            double d = 0.0;
            for (int i = 0; i < 2; i++) d = d + x[i] * x[i];
            return Math.Sqrt(d);
        }

        public double distance(P2D val)
        {
           double d = 0.0;
           for (int i = 0; i < 2; i++) d = d + Math.Pow(x[i]-val.x[i],2);
           return Math.Sqrt(d);
        }
}

class Tester
{
        static void Main(string[] args)
        {
            P2D P1 = new P2D(3.0, 4.0);
            Point<P2D> C1 = new Point<P2D>(P1);
            Console.WriteLine(C1.dist());
        }
} 

详细的代码并不重要。

为什么在通用类Point<T>需要约束where T : IDistance<T> Point<T>

当我仅指定已经实现接口IDistance<T>类(例如P2D类)时,是否应该不已经在Point类中隐式实现了接口呢?

我得到的事实是,当定义了类Point类型<T>的类但未实现接口时,它可能会导致问题。 但是在这种情况下,为什么不可能呢?

Point<T>查看以下代码:

T obj;
public double dist(T val) { return obj.distance(val); 

当编译器试图了解此表达式的含义时:

obj.distance(val)

它必须解决distance成员。 如果T是不受约束的,则不能这样做。 T被约束实现IDistance<T> ,它可以-将其解析为接口的成员。

特别是,在没有约束的情况下,我可以以非常奇怪的方式使用类型:

Point<string> weird = new Point<string>("foo");
double result = weird.dist("bar");

您希望这样做吗?

(作为一个旁注,遵循常规的.NET命名约定,即使是示例也是值得的。方法应为PascalCased,并且我永远也不会调用P2D类...)

我为什么需要这个?

您需要约束,因为您将泛型类型限制为IDistance<T>接口的实现。 如果是Point类,则可以使用这种类型的某些方法,例如obj.distance(val);

您还可以使用抽象类来限制派生。 看一下MSDN中的文档。 http://msdn.microsoft.com/zh-CN/library/bb384067.aspx

当我仅指定已经实现接口IDistance的类(例如Class P2D)时,该接口是否应该已经在Class Point中隐式实现? 我得到一个事实,即当定义为Class Point中的类型的类但未实现接口时,它可能会引起问题。 但是在这种情况下,为什么不可能呢?

因为C#是一种具有编译时类型安全性的语言。 如果没有约束,你可能永远只能实例化Point<T>与值T在运行时,其执行IDistance<T>但有没有办法让编译器知道在编译时,你会这么乖巧。

class Point<T> where T : IDistance<T>  //why do i need this?

您需要这样做是因为您声明的类应将实现IDistance<T>接口的类型作为类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM