运算符重载,以及迭代器[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
目录
相关文章
UE4 Animation Layers功能学习
UE4 Animation Layers功能学习
420 0
UE4 Animation Layers功能学习
解决win11开启移动热点共享手机连上后无法上网的问题
本文提供了解决Windows 11开启移动热点后手机无法上网问题的步骤:通过控制面板进入网络和共享中心,在以太网属性中勾选“允许其他网络用户通过此计算机的Internet连接来连接”,然后手机重新连接共享热点即可上网。
|
编译器 Linux 开发者
【cmake 交叉编译配置设置】CMAKE_TOOLCHAIN_FILE:跨平台编译的秘密武器
【cmake 交叉编译配置设置】CMAKE_TOOLCHAIN_FILE:跨平台编译的秘密武器
1978 0
|
存储 编译器 C++
《C++避坑神器·十五》动态库只有dll文件,没有.lib文件时动态调用dll的中类和成员函数
《C++避坑神器·十五》动态库只有dll文件,没有.lib文件时动态调用dll的中类和成员函数
1056 0
|
自然语言处理 Java 测试技术
序列化性能之巅:使用Fury替换Protobuf/Flatbuffers实现10倍加速
问题背景Protobuf/Flatbuffers是业界广泛使用的序列化库,服务于大量的业务场景。但随着业务场景的复杂化,Protobuf/Flatbuffers逐渐不能满足性能需求开始成为系统瓶颈,在这种情况下,用户不得不手写大量序列化逻辑来进行极致性能优化,但这带来了三个问题:大量字段手写序列化逻辑冗长易出错;手写重复序列化逻辑开发效率低下;难以处理发送端和接收端字段变更的前后兼容性问题;这里将
5013 0
序列化性能之巅:使用Fury替换Protobuf/Flatbuffers实现10倍加速
|
Java Linux API
Android 是怎么捕捉 native 异常的
Android 是怎么捕捉 native 异常的
864 0
|
移动开发 异构计算 索引
进击的 Vulkan 移动开发之 Command Buffer
此篇文章继续学习 Vulkan 中的组件:Command-Buffer 。
836 0
进击的 Vulkan 移动开发之 Command Buffer
|
XML Android开发 数据格式
|
Android开发
Android_打开多个Activity,返回到第一个Activity
正文   一、流程截图        二、问题说明     依次从登录到三级界面,然后退出回到登录界面。     三、解决办法     3.1  实现代码       三级界面调用如下代码:         Intent intent = new Intent(context, LoginView.
1363 0
下一篇
oss云网关配置