How about
dynamic
?
If you are willing to pay the run-time cost, and if you are willing to give up on compile-time type check,
dynamic
could help.
C# really lacks generics specialization and (especially if run-time performance matters) compile-time elaboration of generics.
In C++ you can build
type traits based on templates that were elaborated at
compile-time (e.g. a pioneering book on that was and still is
Modern C++ Design[
^]).
The concept is based on three aspects:
- functional programming style for template programming
- define default behavior in a templated item, add specialization for the types in question (e.g. for the several numeric types)
- C++ allows to have values as template parameters (e.g. not only types but also compile-time constants)
Well, C# does not get even close to this :-(
Top be honest, I really dislike this "workaround", but you have at least another option to evaluate for your problem at hand.
Cheers
Andi
PS: here goes some sample code:
[AttributeUsage(AttributeTargets.Class)]
public class MyAttrAttribute : Attribute
{
public dynamic Arg { get; private set; }
public MyAttrAttribute(object arg)
{
Arg = arg;
}
public static MyAttrAttribute GetAttribute(Type owner)
{
return (from a in owner.GetCustomAttributes(false)
where a.GetType() == typeof(MyAttrAttribute)
select a
).FirstOrDefault() as MyAttrAttribute;
}
}
[MyAttr(123)]
public class MyClassWithIntAttr
{
public MyClassWithIntAttr()
{
var attr = MyAttrAttribute.GetAttribute(
MethodBase.GetCurrentMethod().DeclaringType);
Console.WriteLine("{0} = {1}", attr, attr.Arg + 42);
}
}
[MyAttr(3.14159265358)]
public class MyClassWithDoubleAttr
{
public MyClassWithDoubleAttr()
{
var attr = MyAttrAttribute.GetAttribute(
MethodBase.GetCurrentMethod().DeclaringType);
Console.WriteLine("{0} = {1}", attr, attr.Arg + 42);
}
}
class Program
{
public static void Main()
{
MyClassWithIntAttr c1 = new MyClassWithIntAttr();
MyClassWithDoubleAttr c2 = new MyClassWithDoubleAttr();
}
Output:
Sample.MyAttrAttribute = 165
Sample.MyAttrAttribute = 45.14159265358