I'm trying to write generic algorithms in C# that can work with geometric entities of different dimension.
In the following contrived example I have Point2
and Point3
, both implementing a simple IPoint
interface.
Now I have a function GenericAlgorithm
that calls a function GetDim
. There are multiple definitions of this function based on the type. There is also a fall-back function that is defined for anything that implements IPoint
.
I initially expected the output of the following program to be 2, 3. However, it is 0, 0.
interface IPoint {
public int NumDims { get; }
}
public struct Point2 : IPoint {
public int NumDims => 2;
}
public struct Point3 : IPoint {
public int NumDims => 3;
}
class Program
{
static int GetDim<T>(T point) where T: IPoint => 0;
static int GetDim(Point2 point) => point.NumDims;
static int GetDim(Point3 point) => point.NumDims;
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim(point);
static void Main(string[] args)
{
Point2 p2;
Point3 p3;
int d1 = GenericAlgorithm(p2);
int d2 = GenericAlgorithm(p3);
Console.WriteLine("{0:d}", d1); // returns 0 !!
Console.WriteLine("{0:d}", d2); // returns 0 !!
}
}
OK, so for some reason the concrete type information is lost in GenericAlgorithm
. I don't fully understand why this happens, but fine. If I can't do it this way, what other alternatives do I have?
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
C is a structured, procedural programming language that has been widely used both for operating systems and applications and that has had a wide following in the academic community. Many versions of UNIX-based operating systems are written in C.
This method:
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim(point);
... will always call GetDim<T>(T point)
. The overload resolution is performed at compile-time, and at that stage there's no other applicable method.
If you want overload resolution to be called at execution time, you'd need to use dynamic typing, e.g.
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim((dynamic) point);
But it's generally a better idea to use inheritance for this - in your example, obviously you could just have the single method and return point.NumDims
. I assume in your real code there's some reason the equivalent is trickier to do, but without more context we can't advise on how to use inheritance to perform the specialization. Those are your options though:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With