[ACCEPTED]-Is there a C# generic constraint for "real number" types?-constraints
You can't define such a constraint, but 14 you could check the type at runtime. That 13 won't help you for doing calculations though.
If 12 you want to do calculations, something like 11 this would be an option:
class Calculations<T, S> where S: Calculator<T>, new()
{
Calculator<T> _calculator = new S();
public T Square(T a)
{
return _calculator.Multiply(a, a);
}
}
abstract class Calculator<T>
{
public abstract T Multiply(T a, T b);
}
class IntCalculator : Calculator<int>
{
public override int Multiply(int a, int b)
{
return a * b;
}
}
Likewise, define 10 a FloatCalculator
and any operations you need. It's not 9 particularly fast, though faster than the 8 C# 4.0 dynamic
construct.
var calc = new Calculations<int, IntCalculator>();
var result = calc.Square(10);
A side-effect is that 7 you will only be able to instantiate Calculator
if 6 the type you pass to it has a matching Calculator<T>
implementation, so 5 you don't have to do runtime type checking.
This 4 is basically what Hejlsberg was referring 3 to in this interview where the issue is discussed. Personally 2 I would still like to see some kind of base 1 type :)
This is a very common question; if you are 6 using .NET 3.5, there is a lot of support 5 for this in MiscUtil, via the Operator
class, which supports 4 inbuilt types and any custom types with 3 operators (including "lifted" operators); in 2 particular, this allows use with generics, for example:
public static T Sum<T>(this IEnumerable<T> source) {
T sum = Operator<T>.Zero;
foreach (T value in source) {
if (value != null) {
sum = Operator.Add(sum, value);
}
}
return sum;
}
Or 1 for another example; Complex<T>
This is a known problem, since none of the 5 arithmetic classes arrive from the same 4 class. So you cannot restrict it.
The only 3 thing you could do is
where T : struct
but thats not exactly 2 what you want.
Here is a link to the specific 1 issue.
Arithmetic types like int,double,decimal should implement IArithmetic<T>
You actually can do this, although the solution 23 is tedious to set up, and can be confusing 22 to devs who are not aware of why it was 21 done. (so if you elect to do it document 20 it thououghly!)...
Create two structs, called 19 say, MyInt, and MyDecimal which act as facades 18 to the CTS Int32, and Decimal core types 17 (They contain an internal field of that 16 respective type.) Each should have a ctor 15 that takes an instance of the Core CTS type 14 as input parameter..
Make each one implement 13 an empty interface called INumeric
Then, in 12 your generic methods, make the constraint 11 based upon this interface. Downside, everywhere 10 you want to use these methods you have to 9 construct an instance of the appropriate 8 custom type instead of the Core CTS type, and 7 pass the custom type to the method.
NOTE: coding 6 the custom structs to properly emulate all 5 the behavior of the core CTS types is the 4 tedious part... You have to implement several 3 built-in CLR interfaces (IComparable, etc.) and 2 overload all the arithmetic, and boolean 1 operators...
You can get closer with implementing few 8 more
public class Point<T> where T : struct, IComparable, IFormattable, IConvertible,
IComparable<T>, IEquatable<T> {
}
The signature conforms to DateTime
too. I'm 7 not sure if you will be able to specify 6 more types from the framework. Anyway this 5 only solves part of the problem. To do basic 4 numeric operations you will have to wrap 3 your numeric types and use generic methods 2 instead of standard operators. See this SO question for a few 1 options.
C# doesn't currently allow type constraints 2 on value types. i asked a related question 1 not too long ago.
Would this not lend itself to having seperate 3 classes implementing IPoint?
Something like:
public interface IPoint<T>
{
T X { get; set; }
T Y { get; set; }
}
public class IntegerPoint : IPoint<int>
{
public int X { get; set; }
public int Y { get; set; }
}
As 2 the calculations will have to differ in 1 each implementation anyway right?
Dan#
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.