[C#] Can't get the following generics based function to work.

Started by
17 comments, last by Telastyn 14 years, 2 months ago
Getting back to the original question, why isn't there an INumeric interface? Seems like a glaring oversight from the pov of generics.

To the OP, I'd just provide int and double overloads. short, byte and float can upcast.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Advertisement
Thank you for this useful insight into generics guys. I'm thinking overloads are probably going to be a safer bet for C#!

Has anyone got any interesting wrap methods they would like to share?
Quote:Original post by ChaosEngine
Getting back to the original question, why isn't there an INumeric interface? Seems like a glaring oversight from the pov of generics.


How do you define infix operators on an interface?

Quote:
Not really, the behavior of dynamics is to do a runtime lookup of the appropriate methods. It's essentially reflection in disguise. Don't expect dynamic to be some amazing performance band aid for such code, it's not.


Sure, the first invocation is essentially (worse than) reflection. When I did some (admittedly artificial) benchmarking of the DLR's method caching a few months back, it was decidedly better than even delegate invocation over many calls for this sort of basic math ops.

I would be surprised if plain old dynamic invocation wasn't at least as performant as spodi's example, while being far more legible.
Seeing as how I'm partly to blame for this thread, I apologize for posting broken code, to be honest I was mentally "porting" from the C++ version over the the C# version and figured that generics were the closest analog to templates and that they would work roughly the same, despite my lack of in-depth experience working with my own generic types [embarrass] So I'll just keep going in C++ and leave it as an exercise to the read to do the porting [wink]

Quote:Original post by Spa8nky
Has anyone got any interesting wrap methods they would like to share?

I would probably just split it into two cases, value < min and value ≥ min:
template<typename T>T Wrap(T value, T min, T max){	// This part is up to you, if not a precondition	if(max < min)		std::swap(min, max);	const T count = max - min + static_cast<T>(1);	const T offset = (value < min) ? (value - min + static_cast<T>(1)) : (value - min);	const T origin = (value < min) ? max : min;	return (offset % count) + origin;}
I barraged it with a bunch of values and ranges and it appeared to work great. Integral types only, of course, so you'll need specializations for floating-point types.
Because I'm feeling mildly evil... (requires .NET 4)
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1 {    public static class NumericExtension {        public static T FixToRange<T>(this T value, T min, T max){            return (fixToRange(value, min, max));        }        private static dynamic fixToRange(dynamic value, dynamic min, dynamic max) {            if (value < min) {                return (min);            }            if (max < value) {                return (max);            }            return (value);        }    }    class Program {        static void Main(string[] args) {            int x = 4;            double i = 3.14;                        Console.WriteLine(x.FixToRange(0, 2));            Console.WriteLine(i.FixToRange(3, 3.5));            Console.WriteLine(4.FixToRange(0, 6));            Console.WriteLine(3.14.FixToRange(0, 3));        }    }}


23.1443


And there you are. One dynamic extension method to fix arbitrary things to ranges (and throw exceptions for things that doesn't implement less-than). The actual implementation probably should get argument checking.

[Edited by - Telastyn on February 16, 2010 7:16:22 AM]
The use of dynamic there is completely unnecessary.

public static T Clamp(T value, T min, T max) where T : IComparable<T>{    if (value.CompareTo(min) < 0)        return min;    if (value.CompareTo(max) > 0)        return max;    return value;}
Mike Popoloski | Journal | SlimDX
Quote:Original post by Mike.Popoloski
The use of dynamic there is completely unnecessary.
I should just point out that this is not what the OP was asking for... it was supposed to be a "wrap" operation, not a "clamp" operation, and I can't see a way to do "wrap" with generics.
Quote:
it was supposed to be a "wrap" operation, not a "clamp" operation, and I can't see a way to do "wrap" with generics.


Generics and wrapping seem completely out of reach for me so I am happy to overload any non generics method you guys care to share also.
Quote:Original post by Mike.Popoloski
The use of dynamic there is completely unnecessary.


To be pedantic, IComparable and 'implements operator<' are different criteria. string for example works in one and not the other. It's also important for any sort of situation where you want a 'INumeric' sort of behavior.

This topic is closed to new replies.

Advertisement