本帖最后由 Ivony 于 2008-03-14 10:46:40 编辑

解决方案 »

  1.   

    Sorry,代码有误,样例代码返回值应该是T
      

  2.   

    直接使用应该是不可以的吧 ,c#是类型安全的可以通过编写一个新的类,
    继承object类,在用 typeof 里面分情况进行强制转换并进行计算,不过
    我没有试过
      

  3.   

    很有意思,也很有实际用途的问题。考虑加上个 where T: struct,但仍然无法使用四则运算。
      

  4.   

    看看intdouble的C#定义,没有一个特性或接口是表明可以进行四则运算的,真遗憾:
    // System.Int32 结构
    [SerializableAttribute]
    [ComVisibleAttribute(true)]
    public struct Int32 : IComparable, IFormattable, 
    IConvertible, IComparable<int>, IEquatable<int>// System.Double 结构 
    [SerializableAttribute]
    [ComVisibleAttribute(true)]
    public struct Double : IComparable, IFormattable, 
    IConvertible, IComparable<double>, IEquatable<double>是不是可以考虑加个这方面的特性(Attribute)?
      

  5.   

    其实不仅是加、减、乘、除(+、-、*、/),还有取模(%),逻辑与、或、异或(&、|、^),移位(<<、>>),比较(<、>、<=、>=、==、 !=)等等。
      

  6.   

    提出这个问题Ninputer肯定是已经有自己秘门的解决方案了,而我,现在也不过想到做一个统一浮点数和整型的超数值类。这个类型可以无失真的保存整形和浮点型的数据,并可以从整形和浮点型隐式类型转换过来。
      

  7.   

    但是如果我写算法时可以不关心数据的具体类型,只是做出一些假设:它支持类型内部的+-*/,而且诸如+法的结果还是T(像DateTime就没法进行四则运算)。有些类型,如int和double是内置运算符;而有些类型如Decimal和自定义的Complex是通过运算符重载来实现的。就我所知,解决这两种就解决所有的了。老实说我还没有“秘门”方案的具体代码出来。
      

  8.   


    如果不是整型,就没有取模(%),逻辑与、或、异或(&、 ¦、^),移位( < <、> > )这些运算。而大小比较可以通过IComparable<>来实现。所以就剩下+-*/这写四则运算问题了。
      

  9.   

    直接引用Microsoft.VisualBasic.dll,用里面的Microsoft.VisualBasic.CompilerServices.Operators类
    从object级别解决问题,就是效率不怎么样
      

  10.   

    IComparable 实现可以通过匿名函数 接口实现函数=Delegate(参数a,b){
    if(a大于b)return 1;否则返回-1;相等时是0 
    }这样代码简洁。例如: L.Sort( 
                                    delegate(KeyValuePair <String,   int>   a,   KeyValuePair <String,   int>   b) 
                                    { 
                                            return   (a.Value   -   b.Value); 
                                    } 
                            ); 
    如果不用上面的,就要这样写,增加一个类: 
            internal   class   myCompare   :   System.Collections.Generic.IComparer <KeyValuePair <String,   int> > 
            {               public   int   Compare(KeyValuePair <String,   int>   a,   KeyValuePair <String,   int>   b) 
                    { 
                            return   (a.Value   -   b.Value); 
                    }   
            } 
    //凋用的地方这样写: 
                            myCompare   mp=new   myCompare(); 
                            L.Sort(mp.Compare);
      

  11.   

    如果是比较大小,可以这样用:using System;class Test
    {
      static void Main()
      {
        Console.WriteLine(Max(1));                               // 输出: 1
        Console.WriteLine(Max(.3, -.5));                         // 输出: 0.3
        Console.WriteLine(Max(0M, -3M, 3.14M));                  // 输出: 3.14
        Console.WriteLine(Max(9f, -1f, 3.14f, -2.718f));         // 输出: 9
        Console.WriteLine(Max(0u, 23u, 3114u, 120718u, 5678u));  // 输出: 120718
      }  static T? Max<T>(params T[] x)
      where T: struct, IComparable
      {
        if (x.Length == 0) return null;
        T a = x[0];
        foreach (T i in x)
          if (a.CompareTo(i) < 0) a = i;
        return a;
      }
    }
      

  12.   

    C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性。此外,C# 并不尝试提供 C++ 模板所提供的所有功能。在实现层面,主要区别在于,C# 泛型类型替换是在运行时执行的,从而为实例化的对象保留了泛型类型信息。有关更多信息,请参见运行库的泛型(C# 编程指南)。以下是 C# 泛型和 C++ 模板之间的主要差异: C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。C# 不允许非类型模板参数,如 template C<int i> {}。C# 不支持显式专用化,即特定类型的模板的自定义实现。C# 不支持部分专用化:类型参数子集的自定义实现。C# 不允许将类型参数用作泛型类型的基类。C# 不允许类型参数具有默认类型。在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。
      

  13.   

    比较大小现在已经有比较完美的方案,那就是使用Comparer<T>.Default,使用这个类进行比较,所有实现了IComparable<T>和IComparable的类型都能比较,而且不需要约束。
      

  14.   

    public T MyAlgorithm<T>(T x, T y) where T : struct, IConvertible
    {
        if (typeof(T) == typeof(DateTime)) //手动排除不可运算的值类型...
        {
            throw new ArgumentException("T");
        }
        
        return x + y; //或者使用 IConvertible 辅助处理...
    }
      

  15.   

    实际上我上周末已经解决了重载运算符的问题,现在可支持所有内置类型及全面重载四则运算符的所有类型,还有Nullable类型。但现在有新的问题,要实现通用的泛型算法,光有四则运算还不行,还需要支持常数表达式。比如我要计算1/x就需要有1的表示方法。这个问题可更加头疼了。
      

  16.   

    用vb.net的后期绑定可以很简单的解决这些问题,直接写
    Return x * x + y * y
    就可以了(注意用后期绑定方式编译)
    将编译成使用Microsoft.VisualBasic.CompilerServices.Operators里面的Add等方法的调用不知道,这贴的目的何在
    如果,就是为了实现T的+-*/(包括与常数之间),用VB.net的后期绑定就可以了,不想用vb.net,也可以直接用Microsoft.VisualBasic.CompilerServices.Operators也可以解决问题
    如果,要效率,直接重载最高效,其他方式都不怎么样
      

  17.   


    实际上你提供的就是后期绑定的方案,关键是当期版本的后期绑定总是使用纯反射调用,性能非常不堪。我将会把我暂时的方案贴出来,是已经解决了内置类型和所有全面重载四则运算符类型(如Decimal)的版本。
      

  18.   

    使用C#Lambda进行泛型参数的数值运算
    http://catouse.com/?p=21
    不知道这样实现有没有错
      

  19.   

    public static T max(T t1, T t2)
    {
         return Convert.ToDouble(t1) > Convert.ToSingle(t2) ? t1 : t2;
    }
    这样运算行不行?
      

  20.   

    首先针对T加类型限定:
    T MyAlgorithm<T>(T x, T y) wher T: B
    B 必须为引用类型,同时B有针对 + 运算做操作符重载。
    那么这种方式就限定死了 T 类型必须为引用类型,那么 int, decimal, float这些都不行了。
      

  21.   

            public T intSum<T>(T x, T y)
            {
                if (x.GetType().Equals("Int32") && y.GetType().Equals("Int32"))
                {
                    int result;
                    result = Convert.ToInt32(x) + Convert.ToInt32(y);
                    return result;
                }
           else
                {
                    Console.Write("参数类型不正确!");
                }
            }
    怎么样解决 返回值的类型不同呢