C#复杂变量与函数
接着上一篇《C#总结之变量与流程控制》,来继续总结C#的基础语法,这篇主要总结枚举,结构,数组,字符串等复杂变量,函数的使用及错误异常的处理及调试排查。
文章目录
1. 枚举
枚举使用一个基本类型来存储,默认类型是Int,枚举的基本类型可以是byte,sbyte,short,ushort,int,uint,long,ulong。默认情况下根据定义的顺序从0开始,被自动赋予对应的基本类型值。
// 枚举
enum orientaion:byte
{
north=1,
south=2,
east=3,
west=4
}
// 枚举使用
byte diretionByte;
string directionString;
orientaion myDirection = orientaion.north;
WriteLine($"myDirection is {myDirection}");
diretionByte = (byte)myDirection;
orientaion myDirection3 = (orientaion)diretionByte;
// 枚举转字符串
directionString = Convert.ToString(myDirection);
// 字符串转枚举
string myString = "north";
orientaion myDirection2 = (orientaion)Enum.Parse(typeof(orientaion), myString);
WriteLine($"myDirection2 is {myDirection2}");
WriteLine($"myDirection3 is {myDirection3}");
WriteLine($"byte equivalent = {diretionByte}");
WriteLine($"string equivalent = {directionString}");
2. 结构
结构就是由几个数据组成的数据结构,这些数据可能具有不同的数据类型。
// 枚举
enum orientaion:byte
{
north=1,
south=2,
east=3,
west=4
}
// 结构体
struct route
{
public orientaion direction;
public double distance;
}
// 结构体使用
route myRoute;
int myDirection = -1;
double myDistance;
WriteLine("1:north \n2:south\n3:east\n4:west\n");
do
{
WriteLine("Select a direction.");
myDirection = ToInt32(ReadLine());
} while ((myDirection < 1) || (myDirection > 4));
WriteLine("Input a distance:");
myDistance = ToDouble(ReadLine());
myRoute.direction = (orientaion)myDirection;
myRoute.distance = myDistance;
WriteLine($"myRoute specifies a direction of {myRoute.direction} and a distance of {myRoute.distance}");
3. 数组
3.1 二维数组
// 数组的声明
int[] myIntArray1 = { 1, 3, 5, 6, 7, 8, 5, 4, 56 };
int[] myIntArray2 = new int[5];
int[] myIntArray3= new int[5]{ 1,2,3,6,5};
const int arraySize = 5;
int[] myIntArray4 = new int[arraySize];
// 循环遍历
string[] friendNames = { "Mike", "Jake", "Tifa","Rola",null,"" };
WriteLine($"Here are {friendNames.Length} of my friends");
for(int i = 0; i < friendNames.Length; i++)
{
WriteLine(friendNames[i]);
}
foreach(string name in friendNames)
{
switch(name)
{
case string t when t.StartsWith("T"):
WriteLine($"This friends name starts with a 'T': {name} and is {t.Length - 1} letters long");
break;
case string e when e.Length == 0:
WriteLine("There is a string in the array with no value");
break;
case null:
WriteLine("There was a 'null' value in the array");
break;
case var x:
WriteLine($"This is the var pattern of type:{x.GetType().Name}");
break;
default:
break;
}
WriteLine($"my friend 's name is {name}");
}
int sum = 0, total = 0, counter = 0, intValue = 0;
int?[] myIntArray = new int?[7] { 5, intValue, 9, 10, null, 2, 99 };
foreach(var integer in myIntArray)
{
++total;
switch (integer)
{
case 0:
WriteLine($"Integer number '{total}' has a default value of 0");
counter++;
break;
case int value:
sum += value;
WriteLine($"Integer number '{total}' has a value of {value}");
counter++;
break;
case null:
WriteLine($"Integer number '{total}' is null");
counter++;
break;
default:
break;
}
}
WriteLine($"{total} total integers, {counter} integers with a value other than 0 or null have a sum value of {sum}");
3.2 多维数组
// 多维数组
double[,] hillHeight = new double[3, 4];
double[,] treeHeight =
{
{ 1,2,3,4},
{ 5,6,7,8},
{ 9,0,1,2}
};
// 数组的数组
int[][] jaggedIntAray = new int[3][];
jaggedIntAray[0] = new int[3];
jaggedIntAray[1] = new int[2];
jaggedIntAray[2] = new int[5];
int[][] jaggedIntAray2 = new int[3][] {
new int[] {1,2,3 },
new int[] {1},
new int[] {1,2,3,4}
};
foreach(int[] dd in jaggedIntAray2)
{
foreach(int d in dd)
{
WriteLine($"d={d}");
}
}
4. 字符串
string myString = "A string";
char myChar = myString[0];
WriteLine($"{myChar}");
char[] myChars = myString.ToCharArray();
// 转换大小写
string strLower = myString.ToLower();
string strUpper = myString.ToUpper();
// 删除空格及指定字符
char[] trimChars = { ' ', 'e', 's' };
string strInput = " sI want to be a painter!e ";
strInput= strInput.Trim(trimChars);
WriteLine(strInput);
// 填充字符
string mystring2 = "dahlin";
WriteLine(mystring2.PadLeft(10,'-'));
// 分割字符串
string mystring3 = "my name is dahlin!";
char[] separator = {' '};
string[] myWords = mystring3.Split(separator);
5. 函数
5.1 定义与使用
// 没有返回值的函数
static void Write()
{
WriteLine("Text output from function!");
}
// 待返回值的函数
static double GetVal(double checkVal)
{
if (checkVal < 5)
{
return 1.2;
}
return 3.4;
}
// 表达式体的方法
static double Multiply(double myVal1, double myVal2) => myVal1 * myVal2;
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Write();
WriteLine(GetVal(3.33));
WriteLine(Multiply(1.3, 2.2));
ReadKey();
}
5.2 参数使用
函数的参数比较常见的有值类型参数,ref引用类型参数,参数数组,out输出类型参数,返回值的类型也可以是元组。函数还包括全局函数,局部函数,结构函数。函数的签名包含函数的名称及其参数。
struct CustomerName
{
public string firstName, lastName;
//结构函数
public string Name() => firstName + " " + lastName;
}
class Program
{
// 参数数组
static string SumVals(string name, params int[] vals)
{
int sum = 0;
foreach(int val in vals)
{
sum += val;
}
return $"name: {name},sum:{sum}";
}
// 引用参数
static void ShowDouble(ref int val)
{
val *= 2;
WriteLine($"val doubled ={val}");
}
static ref int ShowDouble2(ref int val)
{
val *= 2;
return ref val;
}
// out 输出参数
static int MaxValue(int[] intArray,out int maxIndex)
{
int maxVal = intArray[0];
maxIndex = 0;
for(int i = 1; i < intArray.Length; i++)
{
if (intArray[i] > maxVal)
{
maxVal = intArray[i];
maxIndex = i;
}
}
return maxVal;
}
// 返回元祖
static (int max,int min,double average) GetMaxMin(IEnumerable<int> numbers)
{
return (
Enumerable.Max(numbers),
Enumerable.Min(numbers),
Enumerable.Average(numbers)
);
}
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
WriteLine(SumVals("dahlin", 1, 2, 3, 4, 5, 6, 7));
int myNumber = 5;
WriteLine($"myNumber is {myNumber}");
ShowDouble(ref myNumber);
WriteLine($"myNumber is {myNumber}");
// ref的使用
ref int myNumber2 = ref myNumber;
int newMyNumber = ShowDouble2(ref myNumber);
// out 输出参数
int[] myArray = { 1, 2, 3, 65, 74, 4, 58, 4, 21, 54 };
WriteLine($"The maxinum value in myArray is {MaxValue(myArray, out int maxIndex)}");
WriteLine($"at element {maxIndex + 1}");
// 使用元组
IEnumerable<int> numbers = new int[] { 1, 2, 3, 4, 5, 67, 8, 9, 3 };
var result = GetMaxMin(numbers);
WriteLine($"Max number is {result.max} \n Min number is {result.min} \n Average number is {result.average} ");
string text;
for(int i = 0; i < 10; i++)
{
text = $"Line {Convert.ToString(i)}";
WriteLine($"{text}");
}
DoubleIt(5);
// 局部函数
void DoubleIt(int val)
{
val *= 2;
WriteLine($"Local Function - val ={val}");
}
// 结构函数使用
CustomerName myCustomer;
myCustomer.firstName = "dahlin";
myCustomer.lastName = "badnothing";
WriteLine(myCustomer.Name());
ReadKey();
}
}
5.3 高级方法参数
- 可选参数: int myMethod(string myString,bool isFlag=true)
- 命名参数: vat result=myMethod(myString,isFlag:true)
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
string sentence = "The first story is about connecting the dots";
List<string> words;
words = GetWords(sentence);
foreach(string word in words)
{
Write(word + " ");
}
WriteLine("\n");
words = GetWords(sentence, reverseOrder: true, capitalizeWords: true);
foreach(string word in words)
{
Write(word + " ");
}
ReadKey();
}
static List<string> GetWords(
string sentance,
bool capitalizeWords = false,
bool reverseOrder = false,
bool reverseWords = false
)
{
List<string> words = new List<string>(sentance.Split(' '));
if (capitalizeWords)
words = CapitalizeWords(words);
if (reverseOrder)
words = ReverseOrder(words);
if (reverseWords)
words = ReverseWords(words);
return words;
}
static List<string> ReverseWords(List<string> words)
{
List<string> result = new List<string>();
foreach(string word in words)
{
result.Add(ReverseWord(word));
}
return result;
}
static string ReverseWord(string word)
{
StringBuilder sb = new StringBuilder();
for(int characterIndex = word.Length - 1; characterIndex >= 0; characterIndex--)
{
sb.Append(word[characterIndex]);
}
return sb.ToString();
}
static List<string> ReverseOrder(List<string> words)
{
List<string> result = new List<string>();
for (int wordIndex = words.Count - 1; wordIndex >= 0; wordIndex--)
{
result.Add(words[wordIndex]);
}
return result;
}
static List<string> CapitalizeWords(List<string> words)
{
List<string> result = new List<string>();
foreach (string word in words)
{
if (word.Length == 0)
{
continue;
}
if (word.Length == 1)
{
result.Add(word[0].ToString().ToUpper());
}
else
{
result.Add(word[0].ToString().ToUpper() + word.Substring(1));
}
}
return result;
}
6. 委托初步
委托是一种存储函数引用的类型
class Program
{
delegate double ProcessDelegate(double param1,double param2);
static double Multiply(double param1, double param2) => param1 * param2;
static double Divide(double param1, double param2) => param1 / param2;
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
ProcessDelegate process;
WriteLine("Enter 2 numbers separated with a comma:");
string input = ReadLine();
int commaPos = input.IndexOf(',');
double param1 = ToDouble(input.Substring(0, commaPos));
double param2 = ToDouble(input.Substring(commaPos + 1,input.Length-commaPos-1));
WriteLine("Enter M to Multiply or D to divide:");
input = ReadLine();
if (input == "M")
{
// process = new ProcessDelegate(Multiply);
process = Multiply;
}
else
{
// process = new ProcessDelegate(Divide);
process = Divide;
}
WriteLine($"Result:{process(param1, param2)}");
ReadKey();
}
}
7. 错误调试
7.1 输出调试信息
输出调试信息可以使用 System.Diagnostics;中的Debug.WriteLine("")和Trace.WriteLine("")等。具体可以参见这篇关于调试信息的博客《C# 调试日志封装》
using System.Diagnostics;
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
int[] testArray = { 4, 5, 6, 4, 5, 3, 6, 6, 9, 9 };
int maxVal = Maxima(testArray, out int[] maxValIndices);
WriteLine($"Maximum value {maxVal} found at element indices");
foreach(int index in maxValIndices)
{
WriteLine(index);
}
ReadKey();
}
static int Maxima(int[] integers,out int[] indices)
{
Debug.WriteLine("Maximum value search started.");
indices = new int[1];
int maxVal = integers[0];
indices[0] = 0;
int count = 1;
Debug.WriteLine(string.Format($"Maximum value initialized to {maxVal} ,at element index index 0."));
for(int i = 1; i < integers.Length; i++)
{
Debug.WriteLine(string.Format($"Now looking at element at index {i}."));
if (integers[i] > maxVal)
{
maxVal = integers[i];
count = 1;
indices = new int[1];
indices[0] = i;
Debug.WriteLine(string.Format($"New maximum found. New value is {maxVal},at element index {i}"));
}
else
{
if (integers[i] == maxVal)
{
count++;
int[] oldIndices = indices;
indices = new int[count];
oldIndices.CopyTo(indices, 0);
indices[count - 1] = i;
Debug.WriteLine(string.Format($"Duplicate maximum found at element index {i}."));
}
}
}
Trace.WriteLine(string.Format($"Maximum value {maxVal} found, with {count} occurrences."));
Debug.WriteLine("Maximum value search completed.");
return maxVal;
}
7.2 错误处理
和大多数编程语言错误异常处理一样,无非就是try/catch/finally/throw
static string[] eTypes = { "none", "simple", "index", "nested index", "filter" };
/// <summary>
/// 主入口函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
foreach(string eType in eTypes)
{
try
{
WriteLine("Main() try block reached.");
WriteLine($"TrowExecption(\"{eType}\") called.");
WriteLine("Main() try block continues.");
}
catch(System.IndexOutOfRangeException e) when (eType=="filter")
{
BackgroundColor = ConsoleColor.Red;
WriteLine("Main() Filtered System.IndexOutOfRangeException catch block reached. Message:\n\"{e.Message}\"");
}
catch(System.IndexOutOfRangeException e)
{
WriteLine("Main() System.IndexOutOfRangeException catch. block reached message :\n \"{e.Message}\"");
}
catch
{
WriteLine("Main() general catch block reached.");
}
finally
{
WriteLine("Main() finally block reached.");
}
WriteLine();
}
ReadKey();
}
static void ThrowException(string exceptionType)
{
WriteLine($"ThrowException(\"{exceptionType}\") reached.");
switch (exceptionType)
{
case "none":
WriteLine("Not throwing an exception");
break;
case "simple":
WriteLine("Throwing System.Exception.");
throw new System.Exception();
case "index":
WriteLine("Throwing System.IndexOutOfRangeException.");
eTypes[5] = "error";
break;
case "nested index":
try
{
WriteLine("ThrowException(\"nested index\") try block reached.");
WriteLine("ThrowException(\"index\" called.)");
ThrowException("index");
}
catch
{
WriteLine("ThrowException(\"nested index\") general catch block reached.");
throw;
}
finally
{
WriteLine("ThrowException(\"nest index\") finally block reached.");
}
break;
case "filter":
try
{
WriteLine("ThrowException(\"filter\")try block reached.");
WriteLine("ThrowException(\"index\") called.");
ThrowException("index");
}
catch
{
WriteLine("ThrowExceotion(\"filter\") general catch block reached.");
throw;
}
break;
}
}
7.3 定制异常
public class MyException:Exception
{
private string name;
public string Name
{
get { return name; }
}
public MyException(string myname):base("my exception!")
{
name = myname;
}
}
static void Main(string[] args)
{
try
{
throw new MyException("test");
}
catch(MyException e)
{
WriteLine(e.Message);
}
ReadKey();
}