前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >运算符重载,以及迭代器[foreach]示例

运算符重载,以及迭代器[foreach]示例

作者头像
菩提树下的杨过
发布2018-01-22 16:46:39
6160
发布2018-01-22 16:46:39
举报

 以下代码来源于"c#高级编程(第4版)",只不过我对它做了一些注释和修改

代码语言:javascript
复制
using System;

using System.Collections;

using System.Text;

namespace Wrox.ProCSharp.VectorAsCollection

{

    class MainEntryPoint

    {

        static void Main(string[] args)

        {

            Vector Vect1 = new Vector(1.0, 2.0, 5.0);

            Console.WriteLine(Vect1.ToString());

            Console.WriteLine(Vect1.ToString("IJK",null));

            Console.WriteLine(Vect1.ToString("VE", null));

            Vector Vect2 = new Vector(1.0, 2.0, 3.0);

            Console.WriteLine(Vect1 == Vect2);

            Double t = Vect1 * Vect2;

            Console.WriteLine(t);

            foreach (double p in Vect1)

            {

                Console.WriteLine(p);

            }

            Console.ReadLine();

        }

    }

    /// <summary>

    /// 声明一个矢量类(包含基本的x,y,z三个分量)

    /// </summary>

    struct Vector : IFormattable

    {

        public double x, y, z;       

        public Vector(double x, double y, double z)

        {

            this.x = x;

            this.y = y;

            this.z = z;

        }
        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="rhs"></param>

        public Vector(Vector rhs)

        {

            x = rhs.x;

            y = rhs.y;

            z = rhs.z;

        }

        /// <summary>

        /// 重载object类的ToString()方法

        /// </summary>

        /// <returns></returns>

        public override string ToString()

        {

            return "( " + x + " , " + y + " , " + z + " )";

        }
        /// <summary>

        /// 实现IFromattable接口,扩展自己的ToString()方法

        /// </summary>

        /// <param name="format"></param>

        /// <param name="formatProvider"></param>

        /// <returns></returns>

        public string ToString(string format, IFormatProvider formatProvider)

        {

            if (format == null)

                return ToString();

            string formatUpper = format.ToUpper();

            switch (formatUpper)

            {

                case "N":

                    return "|| " + Norm().ToString() + " ||";

                case "VE":

                    return String.Format("( {0:E}, {1:E}, {2:E} )", x, y, z);

                case "IJK":

                    StringBuilder sb = new StringBuilder(x.ToString(), 30);

                    sb.Append(" i + ");

                    sb.Append(y.ToString());

                    sb.Append(" j + ");

                    sb.Append(z.ToString());

                    sb.Append(" k");

                    return sb.ToString();

                default:

                    return ToString();

            }

        }
        /// <summary>

        /// 索引器

        /// </summary>

        /// <param name="i"></param>

        /// <returns></returns>

        public double this[uint i]

        {

            get

            {

                switch (i)

                {

                    case 0:

                        return x;

                    case 1:

                        return y;

                    case 2:

                        return z;

                    default:

                        throw new IndexOutOfRangeException(

                           "Attempt to retrieve Vector element" + i);

                }

            }

            set

            {

                switch (i)

                {

                    case 0:

                        x = value;

                        break;

                    case 1:

                        y = value;

                        break;

                    case 2:

                        z = value;

                        break;

                    default:

                        throw new IndexOutOfRangeException(

                           "Attempt to set Vector element" + i);

                }

            }

        }



        /*  

         * 考虑到精度问题,暂不用下面的写法来实现==运算符的重载

         * public static bool operator == (Vector lhs, Vector rhs)

                 {

                    if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z)

                       return true;

                    else

                       return false;

                 }*/



        private const double Epsilon = 0.0000001;

        



        /// <summary>

        /// 重载==运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static bool operator ==(Vector lhs, Vector rhs)

        {

            if (System.Math.Abs(lhs.x - rhs.x) < Epsilon &&

               System.Math.Abs(lhs.y - rhs.y) < Epsilon &&

               System.Math.Abs(lhs.z - rhs.z) < Epsilon)

                return true;

            else

                return false;

        }



        /// <summary>

        /// 重载!=运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static bool operator !=(Vector lhs, Vector rhs)

        {

            return !(lhs == rhs);

        }





        /// <summary>

        /// 重载+运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static Vector operator +(Vector lhs, Vector rhs)

        {

            Vector Result = new Vector(lhs);

            Result.x += rhs.x;

            Result.y += rhs.y;

            Result.z += rhs.z;

            return Result;

        }



        /// <summary>

        /// 重载*运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static Vector operator *(double lhs, Vector rhs)

        {

            return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);

        }



        /// <summary>

        /// 重载*运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static Vector operator *(Vector lhs, double rhs)

        {

            return rhs * lhs;

        }



        /// <summary>

        /// 重载*运算符

        /// </summary>

        /// <param name="lhs"></param>

        /// <param name="rhs"></param>

        /// <returns></returns>

        public static double operator *(Vector lhs, Vector rhs)

        {

            return lhs.x * rhs.x + lhs.y + rhs.y + lhs.z * rhs.z;

        }



        /// <summary>

        /// 重载GetHashCode(不重载的话,也可编译通过,但编译时会有一个警告)

        /// </summary>

        /// <returns></returns>

        public override int GetHashCode()

        {

                return base.GetHashCode();

        }



        /// <summary>

        /// 重载Equals(不重载的话,也可编译通过,但编译时会有一个警告)

        /// </summary>

        /// <param name="obj"></param>

        /// <returns></returns>

        public override bool Equals(object obj)

        {

                return base.Equals(obj);

        }



        /// <summary>

        /// 返回x,y,z的平方和

        /// </summary>

        /// <returns></returns>

        public double Norm()

        {

            return x * x + y * y + z * z;

        }



        #region enumerator class

        

        public IEnumerator GetEnumerator()

        {

            return new VectorEnumerator(this);

        }



       

        private class VectorEnumerator : IEnumerator //要使用佚代器,必须实现IEnumerator接口

        {

            Vector theVector;      // Vector object that this enumerato refers to 

            int location;   // which element of theVector the enumerator is currently referring to 



            public VectorEnumerator(Vector theVector)

            {

                this.theVector = theVector;

                location = -1;

            }



            public bool MoveNext()

            {

                ++location;

                return (location > 2) ? false : true;

            }



            public object Current

            {

                get

                {

                    if (location < 0 || location > 2)

                        throw new InvalidOperationException(

                           "The enumerator is either before the first element or " +

                           "after the last element of the Vector");

                    return theVector[(uint)location];

                }

            }



            public void Reset()

            {

                location = -1;

            }

        }

        #endregion

    }

}

运行结果:

( 1 , 2 , 5 )

1 i + 2 j + 5 k

( 1.000000E+000, 2.000000E+000, 5.000000E+000 )

False

20

1

2

5

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2007-12-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档