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

简介: 以下代码来源于"c#高级编程(第4版)",只不过我对它做了一些注释和修改using System;using System.Collections;using System.Text;namespace Wrox.
 以下代码来源于"c#高级编程(第4版)",只不过我对它做了一些注释和修改
using  System;
using  System.Collections;
using  System.Text;


namespace  Wrox.ProCSharp.VectorAsCollection
{
    
class MainEntryPoint
    
{
        
static void Main(string[] args)
        
{
            Vector Vect1 
= new Vector(1.02.05.0);

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

            Vector Vect2 
= new Vector(1.02.03.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;
        }


        
enumerator class#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
目录
相关文章
|
2月前
数组方法中的`forEach()`方法和`map()`方法有什么区别?
数组方法中的`forEach()`方法和`map()`方法有什么区别?
|
前端开发 JavaScript API
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
Python函数每日一讲 - frozenset集合函数入门及实例
Python函数每日一讲 - frozenset集合函数入门及实例
C++:模拟实现list及迭代器类模板优化方法
C++:模拟实现list及迭代器类模板优化方法
|
前端开发 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(二)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(二)
|
前端开发 API 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)
|
前端开发 JavaScript 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(三)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(三)
|
前端开发 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(四)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(四)
|
前端开发 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(一)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map
【C++要笑着学】list 核心框架接口的模拟实现 | 运算符重载实现list迭代器 | 妙用模板实现const迭代器(二)
我们在上一章说过,list 其实就是带哨兵位循环双向链表而已,这种链表虽然结构复杂,但是实现起来反而是最简单的,我们在数据结构专栏中有过详细的讲解。
73 0
【C++要笑着学】list 核心框架接口的模拟实现 | 运算符重载实现list迭代器 | 妙用模板实现const迭代器(二)