关于C#的++运算符的重载,隐含了赋值?

liups 2013-11-08 03:09:50
http://blog.csdn.net/mougaidong/article/details/5880181
看上面

最后,instance所引用对象的值确实改变了,但是程序中并没有显式对其赋值,难道是重++引起的?
...全文
323 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
可以自己定义几个运算符重载,例如
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApplication1
{
    public class A
    {
        public List<string> s1 = new List<string>();
        public List<int> s2 = new List<int>();

        public static A operator +(A a, int x)
        {
            a.s2.Add(x);
            return a;
        }

        public static A operator +(A a, string x)
        {
            a.s1.Add(x);
            return a;
        }

        public static A operator ++(A a)
        {
            var b = new A();
            b.s1 = a.s1;
            b.s1.AddRange(a.s2.Select(x => x.ToString()));
            b.s2 = a.s2.Select(x => x + 1).ToList();
            return b;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var a = new A();
            a += 1234;
            a += "1234";
            Debug.Assert(a.s1.Count == 1);
            var b = a++;
            Debug.Assert(b.s2.First() == 1234);
            Debug.Assert(a.s2.First() == 1235);
            Console.ReadKey();
        }
    }
}
这样,我们使用比较精炼的语法来表达我们的意思,而不需要些成那种“方法(参数)”的复杂形式。 没有什么绝对的“可以、不可以”的是非,在一定的尺度下,灵活性最重要。
  • 打赏
  • 举报
回复
引用 4 楼 liups 的回复:
另外还有没有类似的例子呢?(我感觉+=这样的可能算是吧,虽然不能直接重载+=,但是通过重载+间接实现了逻辑上的的语义)。
我以前举过一个例子:
主语 c1 = ....;
谓语 c2 = .....;
宾语 c3 = .....;
句子 clause = c1 + c2 + c3;
http://bbs.csdn.net/topics/360039451
liups 2013-11-08
  • 打赏
  • 举报
回复
问题是对于引用类型: 没看出代码是哪个修改了值! 返回值仅仅用于显示吧?
threenewbee 2013-11-08
  • 打赏
  • 举报
回复
引用 10 楼 liups 的回复:
[quote=引用 9 楼 hdt 的回复:] int a; int i=a++; a 等于多少 i等于多少
从原始代码看,没看出哪里改了instance所引用对象的值! 所以我才有这个疑问的提出。 同时,也是因为按i++,--i这样的语义来理解,才觉得C#是这样处理的。另外,学C++时好象看到一个说法,重载运算符,虽然应该尽量和原始意义一致或接近,但是从语言本身来说并不要求也不能保证语义和原始语义有什么关联! [/quote] 这很简单,我说了,对于值类型,返回一个新的值和直接修改其实没有什么不同,比如 int i = 1; int j = i; i++; 此时j肯定还是1 对于引用类型,你怎么做是你的事情,因为这本身就是一个没有定数,也不存在什么和“原始意义”接近的问题。
liups 2013-11-08
  • 打赏
  • 举报
回复
引用 9 楼 hdt 的回复:
int a; int i=a++; a 等于多少 i等于多少
从原始代码看,没看出哪里改了instance所引用对象的值! 所以我才有这个疑问的提出。 同时,也是因为按i++,--i这样的语义来理解,才觉得C#是这样处理的。另外,学C++时好象看到一个说法,重载运算符,虽然应该尽量和原始意义一致或接近,但是从语言本身来说并不要求也不能保证语义和原始语义有什么关联!
真相重于对错 2013-11-08
  • 打赏
  • 举报
回复
int a; int i=a++; a 等于多少 i等于多少
liups 2013-11-08
  • 打赏
  • 举报
回复
引用 7 楼 hdt 的回复:
想想两种++的语义
什么意思,前置和后置?和我的问题有什么关系吗?
真相重于对错 2013-11-08
  • 打赏
  • 举报
回复
想想两种++的语义
liups 2013-11-08
  • 打赏
  • 举报
回复
修改后得到两段测试代码 一、
using System;
namespace Polymorphy
{

    internal class Program
    {

        static void Main(string[] args)
        {

            AType instance = new AType(100);
            AType i;
            i = instance;

            Console.WriteLine(instance++.data);

            Console.WriteLine((++instance).data);

            Console.WriteLine(instance.data);

            //i输出的为原始值100
            Console.WriteLine(i.data);

            Console.ReadKey();

        }

    };

    class AType
    {

        public int data;

        public AType(int para)
        {

            this.data = para;

        }

        public static AType operator ++(AType para)
        {

            Console.WriteLine("执行重载运算符++");

            return new AType(1 + para.data);

        }

    };

}

二、


using System;
namespace Polymorphy
{

    internal class Program
    {

        static void Main(string[] args)
        {

            AType instance = new AType(100);
            AType i;
            i = instance;

            Console.WriteLine(instance++.data);

            Console.WriteLine((++instance).data);

            Console.WriteLine(instance.data);

            //现在i输出的为原始值102了
            Console.WriteLine(i.data);

            Console.ReadKey();

        }

    };

    class AType
    {

        public int data;

        public AType(int para)
        {

            this.data = para;

        }

        public static AType operator ++(AType para)
        {

            Console.WriteLine("执行重载运算符++");

            para.data++;
            return para;



        }

    };

}

由以上可以看出关键还是重载++返回的究竟是new产生的新对象还是原始对象。如果是返回新对象,则要对instance赋值? 大家觉得呢?
threenewbee 2013-11-08
  • 打赏
  • 举报
回复
引用 4 楼 liups 的回复:
[quote=引用 3 楼 gomoku 的回复:] 不是对象的值变了,而是引用变了。 obj++; 相当于: obj = obj + 1; 这里的+ 1是形象的描述,实际上它应该就是自定义的++运算函数: obj = obj.operator++(); 注意obj引用被改变了。
谢谢,我就是这个意思,可能没有表达清楚。 那么是不是说: ++、--这样的重载根据逻辑上的说语义改变了引用(实际上就是赋值),另外还有没有类似的例子呢?(我感觉+=这样的可能算是吧,虽然不能直接重载+=,但是通过重载+间接实现了逻辑上的的语义)。 请继续指教[/quote] 一般我们不建议对引用类型重载++运算。你可以看到,我在2L的写法,事实上是应该修改原来的对象还是返回一个新的,这个由重载者自己决定。但是有一条,++应该和+运算是统一的。否则就更加混淆了。
liups 2013-11-08
  • 打赏
  • 举报
回复
引用 3 楼 gomoku 的回复:
不是对象的值变了,而是引用变了。 obj++; 相当于: obj = obj + 1; 这里的+ 1是形象的描述,实际上它应该就是自定义的++运算函数: obj = obj.operator++(); 注意obj引用被改变了。
谢谢,我就是这个意思,可能没有表达清楚。 那么是不是说: ++、--这样的重载根据逻辑上的说语义改变了引用(实际上就是赋值),另外还有没有类似的例子呢?(我感觉+=这样的可能算是吧,虽然不能直接重载+=,但是通过重载+间接实现了逻辑上的的语义)。 请继续指教
gomoku 2013-11-08
  • 打赏
  • 举报
回复
不是对象的值变了,而是引用变了。 obj++; 相当于: obj = obj + 1; 这里的+ 1是形象的描述,实际上它应该就是自定义的++运算函数: obj = obj.operator++(); 注意obj引用被改变了。
threenewbee 2013-11-08
  • 打赏
  • 举报
回复
它的程序拷贝了一个新的AType,并且其中的字段加一作为返回值。 当然也可以这么写: public static AType operator ++(AType para) { Console.WriteLine("执行重载运算符++"); para.data++; return para; }

110,572

社区成员

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

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

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