none
C# 上, 如何抽象 "整数" 的运算 RRS feed

  • 问题

  • 我正在写一个算法模版库, 其中一个数据结构, 比如  Something<T> , 这个 T 是 任何定义了 ++ 操作的数据类型, 这个 where 应该怎么写?

    另外,我的结构里很多方法的代码 完全一样 区别只是参数的类型是  byte, ushort, uint,ulong , 也就是为了这4个类型,我几乎每个方法都要写完全相同的4份.  在方法内部, 其实只是对这个  byte, ushort, uint,ulong 类型的参数执行了加法或者减法操作, 以及赋值操作, 但是好像现在难以把这些重构消除重复代码, 一片一片一模一样的代码很让人郁闷.

     byte, ushort, uint,ulong 的父类直接就是ValueType类, 并不存在一个抽象的 "正整数" 或者 "自然数" 这个的类, 而且也没有一个共同的接口定义了 +-等基本数字运算. 

    难道在C#语法许可的范围内,我就必须把几百行代码的若干个方法全部都复制4份仅仅为了不同类型的参数吗?  因为都是值类型, 我也不方便定义类型为object, 而且object上并没有 + 和 - 的操作, 去里面还要 GetType得到类型判断后再unboxed 翻回来, 显然也不靠谱.

    我觉得涉及整数类数据结构的好像都应该遇到类似的问题, 该如何解决呢? 

    另外,我的数据结构是一个特殊的类似二维数组或者矩阵的东西, 因为里面会存非常非常多的元素,所以统一用int是非常浪费的. 



    快乐永远

    2013年7月1日 6:50

全部回复

  • 不太好办。

    因为这个限制条件等于说是你限定了T必须是int,long,double,decimal类型。因为也只有这些类型才支持“++”。

    或许你可以限定T是struct类型,然后判断typeOf(T)是啥类型,然后做操作。

    或者干脆Lambda表达式:

    namespace Csharp
    {
        public struct Algorithm<T> where T : struct
        {
            private T num;
     
            public T Num
            {
                get { return num; }
                set { num = value; }
            }
            private const int NUMBER = 1;
     
            public T AddByOne
            {
                get
                {
                    TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
                    object value=null;
     
                    if(converter.CanConvertTo(typeof(T)))
                    {
                      value =  converter.ConvertTo(NUMBERtypeof(T));
                    }
                    Expression constNum = Expression.Constant(value);
                    ParameterExpression exp = Expression.Parameter(typeof(T));
     
                    Expression result = Expression.Add(expconstNum);
                    return Expression.Lambda<Func<T, T>>(resultexp).Compile().Invoke(num);
                }
            }
     
            public Algorithm(T _num)
            {
                num = _num;
            }
        }
        public class Test
        {
            static void Main(string[] args)
            {
                Algorithm<double> a = new Algorithm<double>(1.0);
                Console.WriteLine(a.AddByOne);
            }
        }
    }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年7月1日 7:33
  • 或者参考:http://www.cnblogs.com/ServiceboyNew/archive/2013/02/27/2934588.html

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report

    2013年7月1日 7:38