Reputation: 537
I got a question for some code:
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());
}
}
The code in detail is rather unimportant.
Why do I need the constrain where T : IDistance<T>
in the generic class Point<T>
?
When I only specify classes that already implemented the interface IDistance<T>
like
Class P2D, shouldn't be the interface already implemented implicit in the class Point
?
I get the fact that it can cause problems, when a class as type <T>
in class Point
is defined that has not implemented the interface. But in this case, why is it not possible?
Upvotes: 1
Views: 244
Reputation: 1503984
Look at this code within Point<T>
:
T obj;
public double dist(T val) { return obj.distance(val);
When the compiler tries to understand what this expression means:
obj.distance(val)
it has to resolve the distance
member. If T
is unconstrained, it can't do that. When T
is constrained to implement IDistance<T>
, it can - it resolves it to the member of the interface.
In particular, without the constraint, I could use the type in very odd ways:
Point<string> weird = new Point<string>("foo");
double result = weird.dist("bar");
What would you expect that to do?
(As a side note, it would be worth following normal .NET naming conventions, even for examples. Methods should be PascalCased, and I'd never call a class P2D
...)
Upvotes: 2
Reputation: 38638
why do i need this?
You need the constraint because you are restricting the generic type to be an implementation of the interface, IDistance<T>
. If Point
class you use some methods from this type like obj.distance(val);
.
You also could use a abstract class to restrict derivations. Take a look at documentation in MSDN. http://msdn.microsoft.com/en-us/library/bb384067.aspx
Upvotes: 1
Reputation: 6975
When I only specify classes that already implemented the interface IDistance like Class P2D, shouldnt be the interface already implemented implicit in the Class Point? I get the fact that it can cause problems, when a class as type in Class Point is defined that has not implemented the interface. But in this case, why is it not possible?
Because C# is a language that has compile-time type safety. Without that constraint, you may only ever instantiate Point<T>
with values of T
at run-time which implement IDistance<T>
, but there's no way for the compiler to know at compile-time that you will be so well-behaved.
Upvotes: 1
Reputation: 53958
class Point<T> where T : IDistance<T> //why do i need this?
You need this becuase the class you declare, should take as type a type that implements the interface called IDistance<T>
Upvotes: 0