Is there a constraint that restricts my generic me

2018-12-31 01:30发布

Can anyone tell me if there is a way with generics to limit a generic type argument T to only:

  • Int16
  • Int32
  • Int64
  • UInt16
  • UInt32
  • UInt64

I'm aware of the where keyword, but can't find an interface for only these types,

Something like:

static bool IntegerFunction<T>(T value) where T : INumeric 

20条回答
琉璃瓶的回忆
2楼-- · 2018-12-31 01:44

Probably the closest you can do is

static bool IntegerFunction<T>(T value) where T: struct

Not sure if you could do the following

static bool IntegerFunction<T>(T value) where T: struct, IComparable
, IFormattable, IConvertible, IComparable<T>, IEquatable<T>

For something so specific, why not just have overloads for each type, the list is so short and it would possibly have less memory footprint.

查看更多
浪荡孟婆
3楼-- · 2018-12-31 01:45

I was wondering the same as samjudson, why only to integers? and if that is the case, you might want to create a helper class or something like that to hold all the types you want.

If all you want are integers, don't use a generic, that is not generic; or better yet, reject any other type by checking its type.

查看更多
妖精总统
4楼-- · 2018-12-31 01:46

I created a little library functionality to solve these problems:

Instead of:

public T DifficultCalculation<T>(T a, T b)
{
    T result = a * b + a; // <== WILL NOT COMPILE!
    return result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Should result in 8.

You could write:

public T DifficultCalculation<T>(Number<T> a, Number<T> b)
{
    Number<T> result = a * b + a;
    return (T)result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Results in 8.

You can find the source code here: https://codereview.stackexchange.com/questions/26022/improvement-requested-for-generic-calculator-and-generic-number

查看更多
呛了眼睛熬了心
5楼-- · 2018-12-31 01:47

This question is a bit of a FAQ one, so I'm posting this as wiki (since I've posted similar before, but this is an older one); anyway...

What version of .NET are you using? If you are using .NET 3.5, then I have a generic operators implementation in MiscUtil (free etc).

This has methods like T Add<T>(T x, T y), and other variants for arithmetic on different types (like DateTime + TimeSpan).

Additionally, this works for all the inbuilt, lifted and bespoke operators, and caches the delegate for performance.

Some additional background on why this is tricky is here.

You may also want to know that dynamic (4.0) sort-of solves this issue indirectly too - i.e.

dynamic x = ..., y = ...
dynamic result = x + y; // does what you expect
查看更多
何处买醉
6楼-- · 2018-12-31 01:50

What is the point of the exercise?

As people pointed out already, you could have a non-generic function taking the largest item, and compiler will automatically convert up smaller ints for you.

static bool IntegerFunction(Int64 value) { }

If your function is on performance-critical path (very unlikely, IMO), you could provide overloads for all needed functions.

static bool IntegerFunction(Int64 value) { }
...
static bool IntegerFunction(Int16 value) { }
查看更多
低头抚发
7楼-- · 2018-12-31 01:50

I think you are misunderstanding generics. If the operation you are trying to perform is only good for specific data types then you are not doing something "generic".

Also, since you are only wanting to allow the function to work on int data types then you shouldn't need a separate function for each specific size. Simply taking a parameter in the largest specific type will allow the program to automatically upcast the smaller data types to it. (i.e. passing an Int16 will auto-convert to Int64 when calling).

If you are performing different operations based on the actual size of int being passed into the function then I would think you should seriously reconsider even trying to do what you are doing. If you have to fool the language you should think a bit more about what you are trying to accomplish rather than how to do what you want.

Failing all else, a parameter of type Object could be used and then you will have to check the type of the parameter and take appropriate action or throw an exception.

查看更多
登录 后发表回答