重载运算符的问题,

qiuruonan 2011-07-17 10:03:20
写一个冒泡算法,是泛型的, 其中需要重载运算符“<",

于是我就在类中重载了。结果报错提示:二元运算符的参数之一必须是包含类型

代码如下:


class Test<T>
{

public static bool operator<(T a, T b)
{
。。。。。。。。。。。。

}


public static void BubbleSort2(T[] a, int n)
{

...........................

}

}


请问正确的重载是什么样的的?



另外,重载为什么必须是static 来修饰?





...全文
97 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2011-07-18
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] array = { 3, 4, 7, 2, 1, 8, 9, 10 };
array.BubbleSort(); //按照数值排序
Console.WriteLine(String.Join(", ", array));
array.BubbleSort((x, y) => y - x); //按照数值反向排序
Console.WriteLine(String.Join(", ", array));
array.BubbleSort((x, y) => x.ToString().CompareTo(y.ToString())); //按照字面排序(10排在2前面)
Console.WriteLine(String.Join(", ", array));
}
}

static class SortHelper
{
public static void BubbleSort<TSource>(this TSource[] source, Func<TSource, TSource, int> compareto = null)
{
if (compareto == null)
{
if (typeof(TSource).GetInterface(typeof(IComparable).ToString(), false) != null)
compareto = (x, y) => (x as IComparable).CompareTo(y);
else
compareto = (x, y) => x.GetHashCode() - y.GetHashCode();
}
for (int i = 0; i <= source.Count(); i++)
{
for (int j = 1; j < source.Count() - i; j++)
{
if (compareto(source[j], source[j - 1]) < 0)
{
TSource temp = source[j - 1];
source[j - 1] = source[j];
source[j] = temp;
}
}
}
}
}
}


给一个更优雅、通用、简洁的实现
huangwenquan123 2011-07-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 qiuruonan 的回复:]

现在在我面前,有一种方法, 代码写三份, 类似C++中的函数重载一样,

但是我觉得这么做,是不是有些烦,能不能进行改进一下,如何改进,?
[/Quote]
你可以用委托实现
    public delegate void BuyTicketDelegate(string name);
class Program
{
public delegate bool SortDelegate(object objA,object objB);
static void Main(string[] args)
{
Student[] stu = { new Student(2, 3.2m), new Student(1, 4.1m), new Student(5, 1.5m), new Student(4, 5.4m), new Student(3, 2.3m) };
Sort(stu, Student.intMehod);
foreach (Student s in stu)
Console.WriteLine(s.ToString());
Console.WriteLine("==================");
Sort(stu, Student.decimalMehod);
foreach (Student s in stu)
Console.WriteLine(s.ToString());
Console.ReadLine();
}
static void Sort(object[] obj,SortDelegate sortMethod)
{
for (int i = 0; i < obj.Length; i++)
{
for (int j = i; j < obj.Length; j++)
{
if (sortMethod(obj[i], obj[j]))
{
object temp = obj[i];
obj[i] = obj[j];
obj[j] = temp;
}
}
}
}
}
public class Student
{
public int id;
public decimal juankuan;
public Student(int id, decimal juankuan)
{
this.id = id;
this.juankuan = juankuan;
}
public static bool intMehod(object objA, object objB)
{
return (objA as Student).id > (objB as Student).id;
}
public static bool decimalMehod(object objA, object objB)
{
return (objA as Student).juankuan > (objB as Student).juankuan;
}
public override string ToString()
{
return this.id + "====" + this.juankuan;
}
}
threenewbee 2011-07-17
  • 打赏
  • 举报
回复
给你一个通用的版本:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class MyComparer<TSource, TResult> : IComparable
{
public TSource source;
public Func<TSource, TResult> Selector;
public Func<TResult, TResult, int> Compareto;
public int CompareTo(object other)
{
return Compareto(Selector(source), Selector(((MyComparer<TSource, TResult>)other).source));
}
public MyComparer(TSource obj, Func<TSource, TResult> selector, Func<TResult, TResult, int> compareto)
{
source = obj;
Selector = selector;
Compareto = compareto;
}
}


class Program
{
static void Main(string[] args)
{
int[] array = { 3, 4, 7, 2, 1, 8, 9, 10 };
BubbleSort(array, x => x.ToString(), (x, y) => x.CompareTo(y));
Console.WriteLine(String.Join(", ", array));
BubbleSort(array, x => x, (x, y) => x - y);
Console.WriteLine(String.Join(", ", array));
}

static void BubbleSort<TSource, TResult>(TSource[] source, Func<TSource, TResult> selector, Func<TResult, TResult, int> compareto)
{
for (int i = 0; i <= source.Count(); i++)
{
for (int j = 1; j < source.Count() - i; j++)
{
if (new MyComparer<TSource, TResult>(source[j], selector, compareto).CompareTo(new MyComparer<TSource, TResult>(source[j - 1], selector, compareto)) < 0)
{
TSource temp = source[j - 1];
source[j - 1] = source[j];
source[j] = temp;
}
}
}
}

}
}


1, 10, 2, 3, 4, 7, 8, 9
1, 2, 3, 4, 7, 8, 9, 10
Press any key to continue . . .
threenewbee 2011-07-17
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class MyComparer<TSource> : IComparable
{
public TSource source;
public Func<TSource, IComparable> selector = x => x as IComparable;
public int CompareTo(object other)
{
return (selector(source) as IComparable).CompareTo(selector(((MyComparer<TSource>)other).source));
}
public MyComparer(TSource obj)
{
source = obj;
}
}


class Program
{
static void Main(string[] args)
{
int[] array = { 3, 4, 7, 2, 1, 8, 9 };
BubbleSort(array);
Console.WriteLine(String.Join(", ", array));
}

static void BubbleSort<T>(T[] source)
{
for (int i = 0; i <= source.Count(); i++)
{
for (int j = 1; j < source.Count() - i; j++)
{
if (new MyComparer<T>(source[j]).CompareTo(new MyComparer<T>(source[j - 1])) < 0)
{
T temp = source[j - 1];
source[j - 1] = source[j];
source[j] = temp;
}
}
}
}

}
}
qiuruonan 2011-07-17
  • 打赏
  • 举报
回复
学习了


[Quote=引用 13 楼 caozhy 的回复:]
我只想告诉lz两点:

重载运算符只能用于自己定义的类型。
比如说,你不能重载 int,double,或者任何一个外部类型的运算符。

另外,对于排序,你可以要求对象提供一个 IComparable 接口。

所以lz的设计整个是不对的,属于用错误的技术去解决错误的问题。
[/Quote]
Icedmilk 2011-07-17
  • 打赏
  • 举报
回复
就是这么回事,一个排序的函数不需要知道判断大小的依据,只需要直接调用比较运算符


你在编写这个泛型函数的时候都不知道这个函数将来可能作用于什么类型,那怎么可能知道判别大小的依据呢



[Quote=引用 10 楼 sp1234 的回复:]

哦,也用不着那么麻烦C# code
public static bool operator <(Test<T> a, Test<T> b)
{
if (a is IComparable)
return ((IComparable)a).CompareTo(b) < 0;
else
return false;
}



这是因为你说的那几个类型……
[/Quote]
threenewbee 2011-07-17
  • 打赏
  • 举报
回复
我只想告诉lz两点:

重载运算符只能用于自己定义的类型。
比如说,你不能重载 int,double,或者任何一个外部类型的运算符。

另外,对于排序,你可以要求对象提供一个 IComparable 接口。

所以lz的设计整个是不对的,属于用错误的技术去解决错误的问题。
  • 打赏
  • 举报
回复
我的意思是,你应该回头看看你自己的最初的想法,你写的“于是我就在类中重载了”。可是这个时候你根本不可能重载,因为你不知道T具体是什么,在Test<T>中是不能为空洞的T对象的运算进行重载的。只有在具体类型的源代码的class中,你才可以重载。
  • 打赏
  • 举报
回复
我上面只是就你的 < 方法而言的。

其实你的概念是混乱的。你定义的Test<T>肯定是要对 T 类型的对象进行运算。那么你怎么去重载两个 T 类型的对象的 < 和 > 呢?

假设你在 Test<T> 上声明 where T: IComparable,那么你就可以在 Test<T> 里边去比较大小。不用纠结什么 > 和 < 重载的问题!
qiuruonan 2011-07-17
  • 打赏
  • 举报
回复
你好


我没有看懂你的意思,
这么说吧,


类Test有个函数,是做排序的,

我希望这个函数,既能对于int ,float,string , 都能够排序,

而不是只是一种数组进行排序。



现在在我面前,有一种方法, 代码写三份, 类似C++中的函数重载一样,

但是我觉得这么做,是不是有些烦,能不能进行改进一下,如何改进,?

望不吝赐教啊。



[Quote=引用 7 楼 icedmilk 的回复:]
你的问题很纠结
你要想重载的是T的运算符,必须用T这个类的静态方法,可是你却无法确定T的具体类型,因为他是个模板参数

从设计角度讲,你的Test类是一个排序类,他就是实现了一个排序算法,他就不该去管<运算符的重载,这不是他应该涉及的。




引用 2 楼 qiuruonan 的回复:

不对啊,还是出错

引用 1 楼 ojlovecd 的回复:
public sta……
[/Quote]
  • 打赏
  • 举报
回复
哦,也用不着那么麻烦
public static bool operator <(Test<T> a, Test<T> b)
{
if (a is IComparable)
return ((IComparable)a).CompareTo(b) < 0;
else
return false;
}


这是因为你说的那几个类型都本身就可以比较,无需再搞什么搞什么包装。类似这里的代码,无需管它具体类型是什么,只要它具有IComparable接口就够了。这就是面向对象编程。
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qiuruonan 的回复:]
我的意思是,

在冒泡排序中,有一句: if(a[j+1]<a[j])

数组a是泛型T, 既可以 用来比较整形,float, string 型。。。。。。



这个冒泡排序算法既可以 用来比较整形,float, string 型。。。。。。


那么,我该如何做呢?
[/Quote]

看来你可能不太明白泛型是什么意思。它不是“既可以是.....又可以是......”的意思。泛型只是一种代码生成器,而不是什么运行时“万能”的转换器。

其实你的这个类型Test<T>有点画蛇添足。不过还是给你多写一句,例如你的
public static bool operator <(Test<T> a, Test<T> b)
{
if (typeof(IComparable).IsAssignableFrom(typeof(T)))
return ((IComparable)a).CompareTo(b) < 0;
else
return ..........你自己的代码;
}
Icedmilk 2011-07-17
  • 打赏
  • 举报
回复
你的问题很纠结
你要想重载的是T的运算符,必须用T这个类的静态方法,可是你却无法确定T的具体类型,因为他是个模板参数

从设计角度讲,你的Test类是一个排序类,他就是实现了一个排序算法,他就不该去管<运算符的重载,这不是他应该涉及的。



[Quote=引用 2 楼 qiuruonan 的回复:]

不对啊,还是出错

引用 1 楼 ojlovecd 的回复:
public static bool operator<(Test<T> a, Test<T> b)
[/Quote]
我姓区不姓区 2011-07-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qiuruonan 的回复:]

不对啊,还是出错

引用 1 楼 ojlovecd 的回复:
public static bool operator<(Test<T> a, Test<T> b)
[/Quote]
出什么错?
  • 打赏
  • 举报
回复
其实编译器的说明写的很清楚了!
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qiuruonan 的回复:]
不对啊,还是出错


引用 1 楼 ojlovecd 的回复:
public static bool operator<(Test<T> a, Test<T> b)
[/Quote]

<与>必须成对出现!
qiuruonan 2011-07-17
  • 打赏
  • 举报
回复
我的意思是,

在冒泡排序中,有一句: if(a[j+1]<a[j])

数组a是泛型T, 既可以 用来比较整形,float, string 型。。。。。。



这个冒泡排序算法既可以 用来比较整形,float, string 型。。。。。。


那么,我该如何做呢?


qiuruonan 2011-07-17
  • 打赏
  • 举报
回复
不对啊,还是出错

[Quote=引用 1 楼 ojlovecd 的回复:]
public static bool operator<(Test<T> a, Test<T> b)
[/Quote]
我姓区不姓区 2011-07-17
  • 打赏
  • 举报
回复
public static bool operator<(Test<T> a, Test<T> b)

110,525

社区成员

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

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

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