static void Main(string[] args)
{
AbsValue<int> ABS = new AbsValue<int>();
AbsValue<double> ABSdouble = new AbsValue<double>();
ABS.X = -5;
ABSdouble.X = 65.3;
Console.WriteLine("Integer absolute value: {0}", Math.Abs(ABS.X));
Console.WriteLine("Double absolute value: {0}", Math.Abs(ABSdouble.X));
Console.ReadLine();
}
}
I don't think that it is correctly, but it seems to work. Can you please give me some advise, how i can make it better?
class AbsValue<T>
{
public T X;
}
There's not a clean way to wrap Math.Abs into a generic function, because 1) the function is not generic but instead designed with overloads for each numeric type, and 2) creating a generic restraint for numeric types is not possible in .NET1.
Even if you did that you'd still have to have a giant switch statement to call the proper Math.Abs overload.
I think I'd find a different problem to solve as a beginner - this one is not an easy learning exercise.
1 You can get close by constraining the parameter to struct, IComparable, IFormattable, but it doesn't really buy you much as you'd have to cast to use any operators or framework math functions.
If you want to do Abs generically you can create an interface and implement it for double and int e.g.:
public interface IAbsNum<T>
{
T Abs(T num);
}
public class IntAbsNum : IAbsNum<int>
{
public int Abs(int num) { return Math.Abs(num); }
}
Related
I wrote a Generic Class:
public class Interval<T> where T : IComparable // for checking that Start < End
{
public T Start { get; set; }
public T End { get; set; }
...
}
And I use this class with DateTime, int, etc.
I need a Duration property that returns a duration like:
public object Duration
{
get
{
return End - Start;
}
}
But when this property is included in my class, the compiler raises a logical error on the - operator.
What can I do to achieve this goal normally, or should I ignore it?
Try something like this:
static void Main(string[] args)
{
Tuple<int, bool> value = JustAMethod<int>(5, 3);
if (value.Item2)
{
Console.WriteLine(value.Item1);
}
else
{
Console.WriteLine("Can't substract.");
}
}
public static Tuple<T, bool> JustAMethod<T>(T arg1, T arg2)
{
dynamic dArg1 = (dynamic)arg1;
dynamic dArg2 = (dynamic)arg2;
dynamic ret;
try
{
ret = dArg1 - dArg2;
return new Tuple<T, bool>(ret, true);
}
catch
{
return new Tuple<T, bool>(default(T), false);
}
}
How this works: first, you convert the arguments to a dynamic type, and you can easily use operators on the dynamic type. If you wouldn't be able to use the operators, then an exception would be thrown at runtime. So, if you try to substract two objects that you actually can't substract, we'll catch the exception and return false as the second item in the Tuple.
This is not possible with generics in C# - at least not directly. It has been a highly requested feature on Connect for a long time.
You will need to make your types implement some interface that has a member that can be used, and constrain the class to that, or use one of the workarounds listed in the Connect bug (none of which are perfect), or a separate approach like MiscUtil's generic operators.
this work
public object Duration
{
get
{
return (dynamic)End - (dynamic)Start;
}
}
but no check, and slow
Check Jon Skeet's Misc Util https://jonskeet.uk/csharp/miscutil/
And here the generic operators by Marc Gravell: https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html
The compiler does this so you don't write buggy code, its the whole point of generics and the concept of type safe programming.
If you need a method that subtracts dates write one that accepts a date, and if you need another one for integers, guess what you should write one for integers. Generics are not there so that the compiler can assume responsibility for any type. Think about it what if I wanted the difference between two objects, how would I do that with your generic method?
Or as #Reed Copsey mentioned you can constrain a class to it.
While this may seem like a major restriction, you need to remember that generics are generic. Of course, the System.Int32 type can work just fine with the binary operators of C#. However, for the sake of argument, if <T> were a custom class or structure type, the compiler cannot assume it has overloaded the +, -, *, and / operators.
I'm just learning about generics and have a question regarding method return values.
Say, I want a generic method in the sense that the required generic part of the method signature is only the return value. The method will always take one string as it's parameter but could return either a double or an int. Is this possible?
Effectively I want to take a string, parse the number contained within (which could be a double or an int) and then return that value.
Thanks.
Something like this?
void Main()
{
int iIntVal = ConvertTo<int>("10");
double dDoubleVal = ConvertTo<double>("10.42");
}
public T ConvertTo<T>(string val) where T: struct
{
return (T) System.Convert.ChangeType(val, Type.GetTypeCode(typeof(T)));
}
You cannot return either a double or an int from a generic method without it also returning any other type.
I might, for example, have a Foo class and your generic parse method, without any constraint, will allow this call to be made:
Foo result = Parse<Foo>("111");
The best that you can do with numbers is constrain on your function by only allowing struct (value-types) to be used.
T Parse<T>(string value) where T : struct;
But this will allow all number types, plus any other value-type.
You can constrain by interface type, but there isn't an INumeric interface on double or int so you're kind of stuck.
The only thing that you can do is throw an exception if the wrong type is passed in - which generally isn't very satisfying.
Your best approach, in this case, is to abandon generics and use separately named methods.
double ParseDouble(string value);
int ParseInteger(string value);
But, of course, this won't help you learn generics. Sorry.
Yes it's possible.
Example:
public T ParseValue<T>(String value) {
// ...
}
You could do something like ...
public TResult Parse<TResult>(string parameter)
{
/* do stuff */
}
And use it like ...
int result = Parse<int>("111");
And then it will depend on your implementation in the Parse method.
Hope it helps.
I'm using the WPF Extended Toolkit ( http://wpftoolkit.codeplex.com/ ).
It has a nice NumericUpDown control that I'd like to use, but internally it uses doubles - which means it uses double.MinValue and double.MaxValue.
I'd like to use the same control, but I need a generic version - for ints it needs to use int.MaxValue/MinValue, for floats float.MaxValue/MinValue, etc. (I think you get the idea :))
So I though about copying the NumericUpDown to a GNumericUpDown, where T would ofcourse be the Type..
But this doesn't work, because a generic Type doesn't have MinValue / MaxValue.
And normally I'd use the 'where' clause to specify a base-type, but this doesn't work as afaik there's no common interface that defines 'MinValue' and 'MaxValue'.
Is there a way to solve this with generics, or do I really need to copy/paste/search&replace the original NumericUpDown for each type ?
Well, given that you can get at the type at execution time, you could rely on the fact that all of the numeric types in .NET have MinValue and MaxValue fields, and read them with reflection. It wouldn't be terribly nice, but easy enough to do:
using System;
using System.Reflection;
// Use constraints which at least make it *slightly* hard to use
// with the wrong types...
public class NumericUpDown<T> where T : struct,
IComparable<T>, IEquatable<T>, IConvertible
{
public static readonly T MaxValue = ReadStaticField("MaxValue");
public static readonly T MinValue = ReadStaticField("MinValue");
private static T ReadStaticField(string name)
{
FieldInfo field = typeof(T).GetField(name,
BindingFlags.Public | BindingFlags.Static);
if (field == null)
{
// There's no TypeArgumentException, unfortunately. You might want
// to create one :)
throw new InvalidOperationException
("Invalid type argument for NumericUpDown<T>: " +
typeof(T).Name);
}
return (T) field.GetValue(null);
}
}
class Test
{
static void Main()
{
Console.WriteLine(NumericUpDown<int>.MaxValue);
Console.WriteLine(NumericUpDown<float>.MinValue);
}
}
Note that if you use this with an inappropriate type, I've tried to force a compile-time error as best I can... but it won't be foolproof. If you manage to find a structure with all the right interfaces but without MinValue and MaxValue fields, then any attempt to use the NumericUpDown with that type will cause an exception to be thrown.
The OP made this comment on another answer:
I want to use these controls in my
XAML. My idea was to create a generic
version, and then create empty classes
like NumericUpDownInt :
GNumericUpDown { } Would that be
the way to go, or is there a
better/cleaner way to your knowledge
If you're going to go that route, then just pass the min and max directly:
class abstract GenericNumericUpDown<T>
{
public GenericNumericUpDown(T min, T max) { ... }
}
class NumericUpDownInt : GenericNumericUpDown<int>
{
public NumericUpDownInt() : base(int.MinValue, int.MaxValue) { ... }
}
class NumericUpDownFloat : GenericNumericUpDown<float>
{
public NumericUpDownFloat() : base(float.MinValue, float.MaxValue) { ... }
}
class NumericUpDownDouble : GenericNumericUpDown<double>
{
public NumericUpDownDouble() : base(double.MinValue, double.MaxValue) { ... }
}
You should get the latest source code for the Extended WPF Toolkit. The updated NumericUpDown control allows you to specify what data type to use in the editor. The following code specifies to use an Int32 as the data type instead of the default double. As you can see this is done by setting the ValueType property on the NumericUpDown control.
<extToolkit:NumericUpDown Grid.Row="1" Value="{Binding Age}" Increment="1" Minimum="18" Maximum="65" ValueType="{x:Type sys:Int32}" />
As this is also useful in Testing scenarios:
You may use extension methods, such that in C#6 (introducing nameof) you could write:
public static class TypeExtension
{
public static T MinValue<T>(this Type self)
{
return (T)self.GetField(nameof(MinValue)).GetRawConstantValue();
}
public static T MaxValue<T>(this Type self)
{
return (T)self.GetField(nameof(MaxValue)).GetRawConstantValue();
}
}
and invoke through some admittedly ugly syntax:
var intMinValue = typeof(int).MinValue<int>();
which in your generic method would be
var typeMinValue = typeof(T).MinValue<T>();
Note, that I am not certain that all primitive types declare their Min/Max values as constants. Use GetValue instead.
Can anyone help me in using Where for generic types?
I was trying to create a function which does ST with a number of type double or int, so I said it should be generic function. But when I try to assign a value to variables of that generic type, I can't because it's not a numerical type. Also, I can't use Where to inherit generic type from int or double data types.
Here is the code:
public static T[,] Unit(int n) where T : PROBLEM
{
T[,] mat = new T[n, n];
for (int i = 0; i < n; i++)
mat[i, i] = (T)1;
return mat;
}
Can anyone help?
Unfortunately one of the shortcomings of C# is that you cannot easily make generic numerical algorithms. You can kind of hack around it, like using this example from MSDN:
public abstract class BaseCalculator<T>
{
public abstract T Add(T arg1,T arg2);
public abstract T Subtract(T arg1,T arg2);
public abstract T Divide(T arg1,T arg2);
public abstract T Multiply(T arg1,T arg2);
}
public class IntCalculator : BaseCalculator<int>
{
public override int Add(int arg1, int arg2)
{
return arg1 + arg2;
}
//Rest of the methods
}
But generally speaking the .Net libraries just have a separate implementation for this sort of thing rather than attempting to use generics.
Not sure what this "Where" is to which you are referring, but you can declare your generic function as
public T Calculate<T>(T x, T y) where T : IComparable<T>
{
// do calculations
}
I believe int and double both implement IComparable<T>.
The constraints system in Generics is still pretty coarse grained. Its still a blunt tool with relatively few options to choose from. A much richer feature set for expressing constraints on type parameters will allow all sorts of sophisticated algos to be designed like pattern based programming etc.
If you only tell me that T is a shirt type that I am looking at ... there aint much I can do with it. But if T is not only a shirt but is actually worn by a hooter with some int[] properties with counts in upper 30's and certain events that I can subscribe to and handle with custom codes then I think it will make programming a little more fun and lively.
You can constrain your generic type parameter to be a struct. Struct represents a value type like int or double. Here's an example from the MSDN article:
public class MyClass<T> where T : struct
{...}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# generic constraint for only integers
Greets!
I'm attempting to set up a Cartesian coordinate system in C#, but I don't want to restrict myself to any one numerical type for my coordinate values. Sometimes they could be integers, and other times they could be rational numbers, depending on context.
This screams "generic class" to me, but I'm stumped as to how to constrict the type to both integrals and floating points. I can't seem to find a class that covers any concept of real numbers...
public class Point<T> where T : [SomeClassThatIncludesBothIntsandFloats?] {
T myX, myY;
public Point(T x, T y) {
myX = x;
myY = y;
}
}
Point<int> pInt = new Point<int>(5, -10);
Point<float> pFloat = new Point<float>(3.14159, -0.2357);
If I want this level of freedom, am I electing for a "typeof(T)" nightmare when it comes to calculations inside my classes, weeding out bools, strings, objects, etc? Or worse, am I electing to make a class for each type of number I want to work with, each with the same internal math formulae?
Any help would be appreciated. Thanks!
You can't define such a constraint, but you could check the type at runtime. That won't help you for doing calculations though.
If you want to do calculations, something like 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 a FloatCalculator and any operations you need. It's not particularly fast, though faster than the C# 4.0 dynamic construct.
var calc = new Calculations<int, IntCalculator>();
var result = calc.Square(10);
A side-effect is that you will only be able to instantiate Calculator if the type you pass to it has a matching Calculator<T> implementation, so you don't have to do runtime type checking.
This is basically what Hejlsberg was referring to in this interview where the issue is discussed. Personally I would still like to see some kind of base type :)
This is a very common question; if you are using .NET 3.5, there is a lot of support for this in MiscUtil, via the Operator class, which supports inbuilt types and any custom types with operators (including "lifted" operators); in 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 for another example; Complex<T>
This is a known problem, since none of the arithmetic classes arrive from the same class. So you cannot restrict it.
The only thing you could do is
where T : struct
but thats not exactly what you want.
Here is a link to the specific issue.
Arithmetic types like int,double,decimal should implement IArithmetic<T>
You actually can do this, although the solution is tedious to set up, and can be confusing to devs who are not aware of why it was done. (so if you elect to do it document it thououghly!)...
Create two structs, called say, MyInt, and MyDecimal which act as facades to the CTS Int32, and Decimal core types (They contain an internal field of that respective type.) Each should have a ctor that takes an instance of the Core CTS type as input parameter..
Make each one implement an empty interface called INumeric
Then, in your generic methods, make the constraint based upon this interface.
Downside, everywhere you want to use these methods you have to construct an instance of the appropriate custom type instead of the Core CTS type, and pass the custom type to the method.
NOTE: coding the custom structs to properly emulate all the behavior of the core CTS types is the tedious part... You have to implement several built-in CLR interfaces (IComparable, etc.) and overload all the arithmetic, and boolean operators...
You can get closer with implementing few more
public class Point<T> where T : struct, IComparable, IFormattable, IConvertible,
IComparable<T>, IEquatable<T> {
}
The signature conforms to DateTime too. I'm not sure if you will be able to specify more types from the framework. Anyway this only solves part of the problem. To do basic numeric operations you will have to wrap your numeric types and use generic methods instead of standard operators. See this SO question for a few options.
This might be helpful. You have to use a generic class to achieve what you want.
C# doesn't currently allow type constraints on value types. i asked a related question not too long ago.
Enum type constraints in C#
Would this not lend itself to having seperate 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 the calculations will have to differ in each implementation anyway right?
Dan#