怎样在泛型类型参数的对象上进行四则运算?

Ninputer 2008-03-14 08:47:28
加精
大家都知道,C#泛型的类型参数(就是常说的<T>)上默认没有任何操作,只能调用Object类才有的成员。通过约束基类和接口的方法可以让它支持基类或接口的成员。但是,如果我想在类型参数的对象上执行四则运算就没有办法做到了,因为任何支持四则运算的类型都没有实现什么特殊的接口。这个功能非常有实际意义,比方说我想让我的算法程序支持int,又支持double,甚至支持今后编写的Complex(复数)类型,但是我只想写一遍算法:


public T MyAlgorithm<T>(T x, T y)
{
return x * x + y * y //No!!不让我使用*运算符
}


同样的问题还延伸到Math类的函数,他们都只能支持具体某些类型的重载,而不能支持类型参数T。在C#中如解决了这个问题,就能实现更加抽象的算法,让多类型的代码更加简单。大家有想法就来说说吧!

本贴参与“C#版可用分回赠活动”计划,对纯接分无视


帮忙修正代码

——Ivony
...全文
1619 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangzhiweiaa 2012-09-19
  • 打赏
  • 举报
回复
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("参数类型不正确!");
}
}
怎么样解决 返回值的类型不同呢
江南小鱼 2012-08-10
  • 打赏
  • 举报
回复
首先针对T加类型限定:
T MyAlgorithm<T>(T x, T y) wher T: B
B 必须为引用类型,同时B有针对 + 运算做操作符重载。
那么这种方式就限定死了 T 类型必须为引用类型,那么 int, decimal, float这些都不行了。
nacl 2011-11-14
  • 打赏
  • 举报
回复
mark,很好的讨论啊。
xiu951321 2010-07-19
  • 打赏
  • 举报
回复
贴出来学习 ,
sky_Great 2010-07-16
  • 打赏
  • 举报
回复
public static T max(T t1, T t2)
{
return Convert.ToDouble(t1) > Convert.ToSingle(t2) ? t1 : t2;
}
这样运算行不行?
cj359864746 2010-04-26
  • 打赏
  • 举报
回复
我今天也在思考这个问题,不知博主什么时候把方法贴出来?我很期待。
werhereforu 2010-03-21
  • 打赏
  • 举报
回复
使用C#Lambda进行泛型参数的数值运算
http://catouse.com/?p=21
不知道这样实现有没有错
lbb85 2008-07-22
  • 打赏
  • 举报
回复
看哈,学习哈!
HenryCCG 2008-05-10
  • 打赏
  • 举报
回复
mark
zspsys 2008-05-04
  • 打赏
  • 举报
回复
跟着大家学习~~~~
Ninputer 2008-03-18
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 vwxyzh 的回复:]
用vb.net的后期绑定可以很简单的解决这些问题,直接写

VB.NET codeReturn x * x + y * y


就可以了(注意用后期绑定方式编译)
将编译成使用Microsoft.VisualBasic.CompilerServices.Operators里面的Add等方法的调用

不知道,这贴的目的何在
如果,就是为了实现T的+-*/(包括与常数之间),用VB.net的后期绑定就可以了,不想用vb.net,也可以直接用Microsoft.VisualBasic.CompilerServices.Operators也可以解决问…
[/Quote]

实际上你提供的就是后期绑定的方案,关键是当期版本的后期绑定总是使用纯反射调用,性能非常不堪。我将会把我暂时的方案贴出来,是已经解决了内置类型和所有全面重载四则运算符类型(如Decimal)的版本。
chengqscjh 2008-03-17
  • 打赏
  • 举报
回复
learn
benyouyong 2008-03-17
  • 打赏
  • 举报
回复
关注下。学习!
wapit 2008-03-17
  • 打赏
  • 举报
回复
mark了再看
Ivony 2008-03-17
  • 打赏
  • 举报
回复
那要有些类型根本就不是数值根本就没有常数呢?

如矢量和集合,它们都可以进行加减乘除……
Ninputer 2008-03-17
  • 打赏
  • 举报
回复
实际上我上周末已经解决了重载运算符的问题,现在可支持所有内置类型及全面重载四则运算符的所有类型,还有Nullable类型。但现在有新的问题,要实现通用的泛型算法,光有四则运算还不行,还需要支持常数表达式。比如我要计算1/x就需要有1的表示方法。这个问题可更加头疼了。
changjiangzhibin 2008-03-17
  • 打赏
  • 举报
回复
Mark
shinaterry 2008-03-17
  • 打赏
  • 举报
回复
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 辅助处理...
}
vwxyzh 2008-03-17
  • 打赏
  • 举报
回复
用vb.net的后期绑定可以很简单的解决这些问题,直接写
Return x * x + y * y

就可以了(注意用后期绑定方式编译)
将编译成使用Microsoft.VisualBasic.CompilerServices.Operators里面的Add等方法的调用

不知道,这贴的目的何在
如果,就是为了实现T的+-*/(包括与常数之间),用VB.net的后期绑定就可以了,不想用vb.net,也可以直接用Microsoft.VisualBasic.CompilerServices.Operators也可以解决问题
如果,要效率,直接重载最高效,其他方式都不怎么样
pgy8288 2008-03-17
  • 打赏
  • 举报
回复
MARK先
加载更多回复(26)

110,477

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧