C# Primer Plus编程练习14.8
要求编一个Rainfall类和RainfallQuarterly类,联系的目的是使用属性器和索引器,以及运算符重载。在其中尝试使用了一下try-catch,遇到的问题在上一篇随笔里已经提到了。给数组赋值时不能使用foreach,因为它不允许修改数组值。其他的也没什么特别的。只是main过于零乱与简单。
ps:程序里所有的int型改成uint比较合适。转换运算符对显式和隐式的声明我和答案相反,可能是角度不一样,并且具体实现也不一样。但public static implicit operator Rainfall(RainfallQuarterly rainfallQuarterly)声明为explicit更好,因为除以4会发生截断造成数据丢失。
ps:程序里所有的int型改成uint比较合适。转换运算符对显式和隐式的声明我和答案相反,可能是角度不一样,并且具体实现也不一样。但public static implicit operator Rainfall(RainfallQuarterly rainfallQuarterly)声明为explicit更好,因为除以4会发生截断造成数据丢失。
using System;
namespace ConsoleApplication1
{
class Rainfall
{
private int[] monthRainfall=new int[12]; //每月降水量
public Rainfall() //默认构造函数,月降水量为0
{
for(int i=0;i<12;i++)
monthRainfall[i]=0;
}
public Rainfall(params int[] monthRainfall) //构造函数,输入值为1至12月的降水量,若参数个数超过12则抛出异常
{
if(monthRainfall.Length>12)
throw new ArgumentOutOfRangeException("一年只有12个月!");
//使用Clone方法,this.monthRainfall=(int[])monthRainfall.Clone();
//this.monthRainfall指向一个新的长为3的数组,this.monthRainfall.Length=3
for(int i=0;i<monthRainfall.Length;i++)
this.monthRainfall[i]=monthRainfall[i];
//不能使用foreach,foreach不允许修改数组值
for(int j=monthRainfall.Length;j<12;j++)
this.monthRainfall[j]=0;
}
public void BrowseAll() //显示全部降水
{
Console.WriteLine("一月降水量:{0}mm",monthRainfall[0]);
Console.WriteLine("二月降水量:{0}mm",monthRainfall[1]);
Console.WriteLine("三月降水量:{0}mm",monthRainfall[2]);
Console.WriteLine("四月降水量:{0}mm",monthRainfall[3]);
Console.WriteLine("五月降水量:{0}mm",monthRainfall[4]);
Console.WriteLine("六月降水量:{0}mm",monthRainfall[5]);
Console.WriteLine("七月降水量:{0}mm",monthRainfall[6]);
Console.WriteLine("八月降水量:{0}mm",monthRainfall[7]);
Console.WriteLine("九月降水量:{0}mm",monthRainfall[8]);
Console.WriteLine("十月降水量:{0}mm",monthRainfall[9]);
Console.WriteLine("十一月降水量:{0}mm",monthRainfall[10]);
Console.WriteLine("十二月降水量:{0}mm",monthRainfall[11]);
Console.WriteLine("平均降水量:{0}mm",Average);
}
public int this[int index] //只读索引,获取一个月的降水量,越界抛出异常
{
get
{
if(index<1||index>monthRainfall.Length)
throw new ArgumentOutOfRangeException("索引越界!");
return monthRainfall[index-1];
}
}
public int Average //只读属性,返回平均降水量
{
get
{
int sum=0;
foreach(int temp in monthRainfall)
{
sum+=temp;
}
return sum/monthRainfall.Length;
}
}
public static Rainfall operator+(Rainfall rainfall1,Rainfall rainfall2) //重载+,将两个成员数组对应值相加得到新对象
{
Rainfall rainfall=new Rainfall(rainfall1[1]+rainfall2[1],rainfall1[2]+rainfall2[2],rainfall1[3]+rainfall2[3],rainfall1[4]+rainfall2[4],rainfall1[5]+rainfall2[5],rainfall1[6]+rainfall2[6],rainfall1[7]+rainfall2[7],rainfall1[8]+rainfall2[8],rainfall1[9]+rainfall2[9],rainfall1[10]+rainfall2[10],rainfall1[11]+rainfall2[11],rainfall1[12]+rainfall2[12]);
return rainfall;
}
public static bool operator>(Rainfall rainfall1,Rainfall rainfall2) //重载>,<,全部以Average属性为比较依据
{
if(rainfall1.Average>rainfall2.Average)
return true;
else
return false;
}
public static bool operator<(Rainfall rainfall1,Rainfall rainfall2)
{
if(rainfall1.Average<rainfall2.Average)
return true;
else
return false;
}
public static implicit operator Rainfall(RainfallQuarterly rainfallQuarterly) //转换运算符,把RainfallQuarterly显式式转为Rallfall
{ //不能把该方法放到RainfallQuarterly中,因为使用了私有变量rainfall.monthRainfall
Rainfall rainfall=new Rainfall();
for(int i=0;i<4;i++)
{
rainfall.monthRainfall[i]=rainfallQuarterly[i+1]/4;
rainfall.monthRainfall[i+4]=rainfallQuarterly[i+1]/4;
rainfall.monthRainfall[i+8]=rainfallQuarterly[i+1]/4;
}
return rainfall;
}
}
class RainfallQuarterly
{
private int[] rainfallSeason=new int[4]; //保存每季度的降水量
public RainfallQuarterly() //默认构造函数,季降水量为0
{
for(int i=0;i<4;i++)
rainfallSeason[i]=0;
}
public RainfallQuarterly(params int[] rainfallSeason) //构造函数,输入值为1至4季的降水量,若参数个数超过4则抛出异常
{
if(rainfallSeason.Length>4)
throw new ArgumentOutOfRangeException("一年只有4个季度!");
for(int i=0;i<rainfallSeason.Length;i++)
this.rainfallSeason[i]=rainfallSeason[i];
for(int j=rainfallSeason.Length;j<4;j++)
this.rainfallSeason[j]=0;
}
public void BrowseAllSeasons() //显示全部降水
{
Console.WriteLine("一季度降水量:{0}mm",rainfallSeason[0]);
Console.WriteLine("二季度降水量:{0}mm",rainfallSeason[1]);
Console.WriteLine("三季度降水量:{0}mm",rainfallSeason[2]);
Console.WriteLine("四季度降水量:{0}mm",rainfallSeason[3]);
}
public int this[int index] //只读索引,获取一个季度的降水量,越界抛出异常
{
get
{
if(index<1||index>rainfallSeason.Length)
throw new ArgumentOutOfRangeException("索引越界!");
return rainfallSeason[index-1];
}
}
public static explicit operator RainfallQuarterly(Rainfall rainfall) //转换运算符,把Rainfall显式式转为RainfallQuarterly,为防止溢出(实际上基本不会)
{ //可以把该方法放到任意相关类中
RainfallQuarterly rainfallQuarterly;
int[] temp=new int[4];
int sum=0;
for(int i=0;i<4;i++)
{
sum=0;
for(int j=i*3;j<(i+1)*3;j++)
{
sum+=rainfall[j+1];
}
temp[i]=sum;
}
rainfallQuarterly=new RainfallQuarterly(temp);
return rainfallQuarterly;
}
}
/// <summary>
/// Test 的摘要说明。
/// </summary>
class Test
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
public static int Main()
{
//
// TODO: 在此处添加代码以启动应用程序
//
int[] array={0,1,2,3,4,5,6,7,8,9,10,11};
RainfallQuarterly rainfallQuarterly=null;
try
{
rainfallQuarterly=new RainfallQuarterly(array);
}
catch(ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
//Rainfall rainfall2=new Rainfall(array);
Rainfall rainfall=null;
//rainfall=rainfall1+rainfall2;
try
{
rainfall=new Rainfall(array);
}
catch(ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
rainfall.BrowseAll();
RainfallQuarterly rainfallSeason=(RainfallQuarterly)rainfall;
rainfallSeason.BrowseAllSeasons();
Rainfall rainfall2=rainfallSeason;
rainfall2.BrowseAll();
//
//结束程序
//
Console.WriteLine("\nThanks for using!\nPress Enter to cancle");
Console.ReadLine();
return(0);
}
}
}
namespace ConsoleApplication1
{
class Rainfall
{
private int[] monthRainfall=new int[12]; //每月降水量
public Rainfall() //默认构造函数,月降水量为0
{
for(int i=0;i<12;i++)
monthRainfall[i]=0;
}
public Rainfall(params int[] monthRainfall) //构造函数,输入值为1至12月的降水量,若参数个数超过12则抛出异常
{
if(monthRainfall.Length>12)
throw new ArgumentOutOfRangeException("一年只有12个月!");
//使用Clone方法,this.monthRainfall=(int[])monthRainfall.Clone();
//this.monthRainfall指向一个新的长为3的数组,this.monthRainfall.Length=3
for(int i=0;i<monthRainfall.Length;i++)
this.monthRainfall[i]=monthRainfall[i];
//不能使用foreach,foreach不允许修改数组值
for(int j=monthRainfall.Length;j<12;j++)
this.monthRainfall[j]=0;
}
public void BrowseAll() //显示全部降水
{
Console.WriteLine("一月降水量:{0}mm",monthRainfall[0]);
Console.WriteLine("二月降水量:{0}mm",monthRainfall[1]);
Console.WriteLine("三月降水量:{0}mm",monthRainfall[2]);
Console.WriteLine("四月降水量:{0}mm",monthRainfall[3]);
Console.WriteLine("五月降水量:{0}mm",monthRainfall[4]);
Console.WriteLine("六月降水量:{0}mm",monthRainfall[5]);
Console.WriteLine("七月降水量:{0}mm",monthRainfall[6]);
Console.WriteLine("八月降水量:{0}mm",monthRainfall[7]);
Console.WriteLine("九月降水量:{0}mm",monthRainfall[8]);
Console.WriteLine("十月降水量:{0}mm",monthRainfall[9]);
Console.WriteLine("十一月降水量:{0}mm",monthRainfall[10]);
Console.WriteLine("十二月降水量:{0}mm",monthRainfall[11]);
Console.WriteLine("平均降水量:{0}mm",Average);
}
public int this[int index] //只读索引,获取一个月的降水量,越界抛出异常
{
get
{
if(index<1||index>monthRainfall.Length)
throw new ArgumentOutOfRangeException("索引越界!");
return monthRainfall[index-1];
}
}
public int Average //只读属性,返回平均降水量
{
get
{
int sum=0;
foreach(int temp in monthRainfall)
{
sum+=temp;
}
return sum/monthRainfall.Length;
}
}
public static Rainfall operator+(Rainfall rainfall1,Rainfall rainfall2) //重载+,将两个成员数组对应值相加得到新对象
{
Rainfall rainfall=new Rainfall(rainfall1[1]+rainfall2[1],rainfall1[2]+rainfall2[2],rainfall1[3]+rainfall2[3],rainfall1[4]+rainfall2[4],rainfall1[5]+rainfall2[5],rainfall1[6]+rainfall2[6],rainfall1[7]+rainfall2[7],rainfall1[8]+rainfall2[8],rainfall1[9]+rainfall2[9],rainfall1[10]+rainfall2[10],rainfall1[11]+rainfall2[11],rainfall1[12]+rainfall2[12]);
return rainfall;
}
public static bool operator>(Rainfall rainfall1,Rainfall rainfall2) //重载>,<,全部以Average属性为比较依据
{
if(rainfall1.Average>rainfall2.Average)
return true;
else
return false;
}
public static bool operator<(Rainfall rainfall1,Rainfall rainfall2)
{
if(rainfall1.Average<rainfall2.Average)
return true;
else
return false;
}
public static implicit operator Rainfall(RainfallQuarterly rainfallQuarterly) //转换运算符,把RainfallQuarterly显式式转为Rallfall
{ //不能把该方法放到RainfallQuarterly中,因为使用了私有变量rainfall.monthRainfall
Rainfall rainfall=new Rainfall();
for(int i=0;i<4;i++)
{
rainfall.monthRainfall[i]=rainfallQuarterly[i+1]/4;
rainfall.monthRainfall[i+4]=rainfallQuarterly[i+1]/4;
rainfall.monthRainfall[i+8]=rainfallQuarterly[i+1]/4;
}
return rainfall;
}
}
class RainfallQuarterly
{
private int[] rainfallSeason=new int[4]; //保存每季度的降水量
public RainfallQuarterly() //默认构造函数,季降水量为0
{
for(int i=0;i<4;i++)
rainfallSeason[i]=0;
}
public RainfallQuarterly(params int[] rainfallSeason) //构造函数,输入值为1至4季的降水量,若参数个数超过4则抛出异常
{
if(rainfallSeason.Length>4)
throw new ArgumentOutOfRangeException("一年只有4个季度!");
for(int i=0;i<rainfallSeason.Length;i++)
this.rainfallSeason[i]=rainfallSeason[i];
for(int j=rainfallSeason.Length;j<4;j++)
this.rainfallSeason[j]=0;
}
public void BrowseAllSeasons() //显示全部降水
{
Console.WriteLine("一季度降水量:{0}mm",rainfallSeason[0]);
Console.WriteLine("二季度降水量:{0}mm",rainfallSeason[1]);
Console.WriteLine("三季度降水量:{0}mm",rainfallSeason[2]);
Console.WriteLine("四季度降水量:{0}mm",rainfallSeason[3]);
}
public int this[int index] //只读索引,获取一个季度的降水量,越界抛出异常
{
get
{
if(index<1||index>rainfallSeason.Length)
throw new ArgumentOutOfRangeException("索引越界!");
return rainfallSeason[index-1];
}
}
public static explicit operator RainfallQuarterly(Rainfall rainfall) //转换运算符,把Rainfall显式式转为RainfallQuarterly,为防止溢出(实际上基本不会)
{ //可以把该方法放到任意相关类中
RainfallQuarterly rainfallQuarterly;
int[] temp=new int[4];
int sum=0;
for(int i=0;i<4;i++)
{
sum=0;
for(int j=i*3;j<(i+1)*3;j++)
{
sum+=rainfall[j+1];
}
temp[i]=sum;
}
rainfallQuarterly=new RainfallQuarterly(temp);
return rainfallQuarterly;
}
}
/// <summary>
/// Test 的摘要说明。
/// </summary>
class Test
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
public static int Main()
{
//
// TODO: 在此处添加代码以启动应用程序
//
int[] array={0,1,2,3,4,5,6,7,8,9,10,11};
RainfallQuarterly rainfallQuarterly=null;
try
{
rainfallQuarterly=new RainfallQuarterly(array);
}
catch(ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
//Rainfall rainfall2=new Rainfall(array);
Rainfall rainfall=null;
//rainfall=rainfall1+rainfall2;
try
{
rainfall=new Rainfall(array);
}
catch(ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
rainfall.BrowseAll();
RainfallQuarterly rainfallSeason=(RainfallQuarterly)rainfall;
rainfallSeason.BrowseAllSeasons();
Rainfall rainfall2=rainfallSeason;
rainfall2.BrowseAll();
//
//结束程序
//
Console.WriteLine("\nThanks for using!\nPress Enter to cancle");
Console.ReadLine();
return(0);
}
}
}