patterncsharpMinor
Is this C# 'hack' a bad idea?
Viewed 0 times
thisideabadhack
Problem
As C# doesn't have generic specialisation like C++ template specialisation and I wanted a way to be able to do it, I came up with a little hack that goes a bit like this:
Other than this not being the 'right way' to do things and being a complete mistreatment of the method overloading system, are there any possible side effects that could happen as a result of this horrible hack?
EDIT:
An applied example of specialisation in such a manner:
```
// assume Specialisation is unchanged
public interface IConvertible // Not to be confused with System.IConvertible
{
T Convert(Specialisation t);
}
public class ConvertMe : IConvertible, IConvertible
{
public double Value;
public int Convert(Specialisation t) { return (int)Value; }
public float Convert(Specialisation t) { return (float)Value; }
}
public static class Program
{
public static void Main()
{
ConvertMe c = new ConvertMe();
c.Value = 12.3456789;
Console.WriteLine
public sealed class Specialisation
{
private Specialisation() { }
private static Specialisation instance = new Specialisation();
public static Specialisation Instance { get { return instance; } }
}
public interface ISpecialisable
{
T SpecialisedMethod(Specialisation t);
}
public class Specialised : ISpecialisable, ISpecialisable
{
public double Value;
public int SpecialisedMethod(Specialisation t) { return (int)Value; }
public float SpecialisedMethod(Specialisation t) { return (float)Value; }
}
public static class Program
{
public static void Main()
{
Specialised s = new Specialised();
s.Value = 12.3456789;
Console.WriteLine(s.SpecialisedMethod(Specialisation.Instance));
Console.WriteLine(s.SpecialisedMethod(Specialisation.Instance));
Console.ReadKey();
}
}Other than this not being the 'right way' to do things and being a complete mistreatment of the method overloading system, are there any possible side effects that could happen as a result of this horrible hack?
EDIT:
An applied example of specialisation in such a manner:
```
// assume Specialisation is unchanged
public interface IConvertible // Not to be confused with System.IConvertible
{
T Convert(Specialisation t);
}
public class ConvertMe : IConvertible, IConvertible
{
public double Value;
public int Convert(Specialisation t) { return (int)Value; }
public float Convert(Specialisation t) { return (float)Value; }
}
public static class Program
{
public static void Main()
{
ConvertMe c = new ConvertMe();
c.Value = 12.3456789;
Console.WriteLine
Solution
First of all, I would question the need for such interface. It makes sense for a type to hold a value, but I think it doesn't make much sense for a type to decide to what types to convert that value, or how.
Second, if you really do need this, then I would prefer each target type to have a separate method, like
You don't necessarily need an interface for this, but even if you do, you're exchanging a small inconvenience in implementation (having to write few very simple interfaces with some repetition) for a big inconvenience in usage (having to write that
Third, if you really do need this and you want to take advantage of generics, you could use explicit interface implementation and casting to decide to what type to convert. Something like:
This results in code that is shorter and more readable (I think) than your version.
One issue with it is that if you don't make
Second, if you really do need this, then I would prefer each target type to have a separate method, like
ConvertToInt() (or ConvertToInt32() if you follow the naming guidelines).You don't necessarily need an interface for this, but even if you do, you're exchanging a small inconvenience in implementation (having to write few very simple interfaces with some repetition) for a big inconvenience in usage (having to write that
Specialisation.Instance every time and making the code less readable). So, I think using this approach is worth it even with interfaces.Third, if you really do need this and you want to take advantage of generics, you could use explicit interface implementation and casting to decide to what type to convert. Something like:
public interface IConvertible
{
T Convert();
}
public sealed class ConvertMe : IConvertible, IConvertible
{
public double Value;
int IConvertible.Convert() { return (int)Value; }
float IConvertible.Convert() { return (float)Value; }
}
public static class Program
{
public static void Main()
{
ConvertMe c = new ConvertMe();
c.Value = 12.3456789;
Console.WriteLine(((IConvertible)c).Convert());
Console.WriteLine(((IConvertible)c).Convert());
}
}This results in code that is shorter and more readable (I think) than your version.
One issue with it is that if you don't make
ConvertMe sealed, trying to convert to an unsupported type becomes a runtime exception, instead of a compile-time error.Code Snippets
public interface IConvertible<T>
{
T Convert();
}
public sealed class ConvertMe : IConvertible<int>, IConvertible<float>
{
public double Value;
int IConvertible<int>.Convert() { return (int)Value; }
float IConvertible<float>.Convert() { return (float)Value; }
}
public static class Program
{
public static void Main()
{
ConvertMe c = new ConvertMe();
c.Value = 12.3456789;
Console.WriteLine(((IConvertible<int>)c).Convert());
Console.WriteLine(((IConvertible<float>)c).Convert());
}
}Context
StackExchange Code Review Q#41775, answer score: 6
Revisions (0)
No revisions yet.