2014-07-02 170 views
1

我得到了一些代码的一个问题:C#泛型约束:接口

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>

当我只指定一个已经实现的接口IDistance<T>像 类P2D班,不应接口已经在类Point实现隐?

我得到这样一个事实,即它可能会导致问题,当类<T>中的类Point被定义为未实现该接口时。但在这种情况下,为什么不可能?

回答

2

看看这段代码的接口类型:

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 ...)

1

为什么我需要这个?

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

您也可以使用抽象类来限制派生。看看MSDN中的文档。 http://msdn.microsoft.com/en-us/library/bb384067.aspx

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

你需要这个监守你声明类,应在Point<T>采取类型实现所谓IDistance<T>

1

当我只指定已经实现类ID P2D的接口IDistance的类,不应该是已经实现的在Class Point中隐含的接口?当Class类中的类被定义为未实现接口时,我得到它可能导致问题的事实。但在这种情况下,为什么不可能?

因为C#是一种具有编译时类型安全性的语言。没有这个限制,你只能在运行时实例化Point<T>,其值为T,它实现IDistance<T>,但编译器在编译时没有办法知道你会如此行事。