文章目录
- 基础部分概述
- 1. 变量:
- 2. 数据类型:
- 3. 运算符:
- 4. 控制语句:
- 5. 字符串和数组:
- 6. 类型转换:
- 7. 输出和输入:
- 8. 变量命名:
- 9. 函数:
- 10. 枚举值的比较:
- 11. 异常处理:
- 12. 接口:
- 13. 委托和事件:
- 14. 匿名方法:
- 15. LINQ(Language Integrated Query):
对于机器视觉中的一些常见方法,我们在前面11篇文章里已经有所了解。
如果想从应用的角度入手,之后就必须对C#/C++的理解与使用更进一步。
在机器视觉中,以C#入手是一个不错的选择,接下来两篇文章,我们简单地过一下C#的基础语法与用法,再开始以WPF入手去理解一些实例,结合halcon/python,来进行更深一步的了解。
本文就以C#的基础语法与常见的名词入手来详细学习。
PS:这里的文章对于C#的内容过一遍,若想系统地学习C#,建议参考C#的官方文档-微软在线文档。
基础部分概述
以下是C#的主要基础概念:
1. 变量:
在程序中,我们需要使用变量来存储数据。变量是一个可以改变的值,它是程序中的一个存储位置。变量在声明时需要指定数据类型。例如:int age;。
2. 数据类型:
C#有多种数据类型,包括整型(Integer)、浮点型(Float/Double)、布尔型(Boolean)、字符串(String)、字符型(Char)、枚举(Enum)、数组(Array)、结构(Struct)等。
- 整型:可以表示正整数、负整数和零。整型可以使用关键字int、long和short来声明。
- 浮点型:用于存储小数,可以表示正数、负数和零。浮点型可以使用关键字double和float来声明。
- 布尔型:用于存储布尔值,即真(True)或假(False)。布尔型可以使用关键字bool来声明。
- 字符串型:用于存储文本字符串。字符串可以使用关键字string来声明。
- 字符型:用于存储单个字符。字符型可以使用关键字char来声明。
- 枚举型:用于定义一组常量值。枚举可以使用关键字enum来声明。
- 数组型:用于存储一组相同类型的数据。数组可以使用关键字int[]、double[]等来声明。
- 结构体(Struct):用于将不同类型的数据组合在一起。结构体可以使用关键字struct来声明。
3. 运算符:
C#提供了丰富的运算符,用于进行算术运算、逻辑运算、关系运算、位运算、赋值运算、比较运算、条件运算、成员运算和求模运算等。例如:+、-、*、/、%、==、!=、>、<、>=、<=等。
4. 控制语句:
C#提供了多种控制语句,用于实现程序的流程控制。常用的控制语句包括if-else、switch-case、for、while、do-while、break、continue、return等。
5. 字符串和数组:
字符串和数组是C#中常用的数据结构。字符串用于存储和操作文本数据,可以使用单引号(')或双引号(")来声明和使用。数组用于存储一组相同类型的数据,可以使用方括号([])来声明和使用。
6. 类型转换:
在C#中,不同数据类型之间可以进行转换。可以使用as运算符进行隐式类型转换,或使用(type)运算符进行显式类型转换。
7. 输出和输入:
在C#中,可以使用System.Console类的ReadLine方法读取用户的输入,或使用Console.WriteLine方法输出程序的输出结果。
下面是一个输入输出实例。
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入您的姓名: ");
string name = Console.ReadLine();
Console.WriteLine("您的姓名是: {0}", name);
Console.WriteLine("请输入一个数字: ");
int number = int.Parse(Console.ReadLine());
Console.WriteLine("您输入的数字是: {0}", number);
}
}
在这个示例中,我们使用Console.WriteLine()方法向用户输出消息。然后我们使用Console.ReadLine()方法从用户那里读取输入,将输入字符串转换为整数,然后将结果输出到控制台。
运行此程序后,用户将看到一个消息提示,要求输入他们的姓名。输入姓名后,程序将显示输入的姓名和用户输入的数字。
8. 变量命名:
C#对变量的命名有一定的规则,例如变量名必须以字母或下划线开始,后面可以跟字母、数字或下划线。变量名应尽量描述变量的用途,避免使用拼音、英文缩写等容易混淆的字符。
9. 函数:
函数是一个命名的代码块,它可以接收参数并返回一个值。C#中使用关键字function声明函数,例如function functionName(parameters) returns value。函数的参数和返回值类型要匹配。
10. 枚举值的比较:
枚举值之间的比较要考虑枚举值的大小关系。例如,int类型的枚举值可以进行算术运算,而DateTime类型的枚举值可以比较日期和时间。
下面是一个枚举实例。
using System;
using System.Globalization;
using System.Threading.Tasks;
public class Program
{
public static void Main(string[] args)
{
DateTime startTime = new DateTime(2019, 9, 14, 12, 00, 00, DateTimeKind.Utc);
DateTime endTime = new DateTime(2019, 9, 14, 20, 00, 00, DateTimeKind.Utc);
string values = Enum.GetNames(typeof(DateTimeFormat)).ToList();
string format = values[Enum.GetName(typeof(DateTimeFormat), startTime.Value.ToString("d"))];
var isBefore = DateTimeFormat.Parse(values[Enum.GetName(typeof(DateTimeFormat), endTime.Value.ToString("d"))]).CompareTo(startTime) < 0;
var isAfter = DateTimeFormat.Parse(values[Enum.GetName(typeof(DateTimeFormat), endTime.Value.ToString("d"))]).CompareTo(startTime) > 0;
Console.WriteLine($"{format} is before {Enum.GetName(typeof(DateTimeFormat), startTime.Value.ToString("d"))} and {Enum.GetName(typeof(DateTimeFormat), endTime.Value.ToString("d"))} is after {Enum.GetName(typeof(DateTimeFormat), startTime.Value.ToString("d"))}.");
Console.ReadKey();
}
}
此示例中,我们首先创建了两个DateTime类型的对象,它们代表不同的日期和时间。然后,我们使用Enum.GetNames方法获取所有可能的日期和时间格式名称,将其转换为字符串并存储在列表中。
接着,我们使用Enum.GetName方法获取每个日期和时间格式的枚举值,并将其转换为DateTime。然后比较两个日期和时间的顺序(即在时间轴上的相对位置),以确定它们之间的关系。接着使用CompareTo方法进行比较,该方法返回一个整数,表示两个对象之间的顺序。如果需要在两个日期和时间之间执行更复杂的操作,可以考虑使用DateTime的其他方法。
11. 异常处理:
C#提供了try、catch和finally关键字来处理异常。当程序出现异常时,try块中的代码将不会被执行,而是直接跳转到catch块。finally块无论是否发生异常都会被执行。
下面是一个异常处理实例:
using System;
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("请输入一个字符串");
string input = Console.ReadLine();
int num = Int32.Parse(input);
Console.WriteLine("你输入的是: " + num);
}
catch (FormatException e)
{
Console.WriteLine("输入格式不正确,请输入一个整数");
}
catch (Exception e)
{
Console.WriteLine("发生了异常,具体原因是: {0}", e.Message);
}
}
}
在这个例子中,我们首先通过Console.ReadLine()获取用户输入的字符串。然后,我们尝试将输入的字符串转换为整数(Int32.Parse(input))。如果转换成功,我们会打印出用户输入的字符串和转换后的整数。
如果用户输入了不符合要求的字符串(例如,尝试输入一个字符),我们将捕获一个FormatException异常,并打印一条提示消息。
如果用户输入的字符串转换为整数失败(例如,尝试输入一个负数),我们将捕获一个Exception异常,并打印出一条错误消息。
注意,catch (Exception e)块是可选的,但它提供了一种捕获任何异常类型的方法。
12. 接口:
接口是一种引用类型,它定义了一组方法、属性和事件的签名,但不包含实现。接口使用关键字interface来声明。接口可以继承其他接口,实现接口的类必须实现接口中定义的所有方法、属性和事件。
下面是一个使用C#语言编写的接口实例。这个接口的定义如下:
interface IAnimal
{
void MakeSound();
}
接下来,我们将创建一个实现了IAnimal接口的类,名为Animal,它包含一个名为MakeSound的方法:
class Animal : IAnimal
{
public void MakeSound()
{
Console.WriteLine("Aww, woof!");
}
}
现在,我们可以创建一个新的对象,并通过IAnimal接口与之交互:
class Program
{
static void Main(string[] args)
{
Animal animal = new Animal();
animal.MakeSound(); // Outputs: Aww, woof!
}
}
输出结果为:
Aww, woof!
这个示例展示了如何创建一个接口、实现该接口的类以及如何使用该接口。在这个示例中,我们创建了一个名为Animal的类,并实现了IAnimal接口的MakeSound方法。然后,我们创建了一个名为animal的Animal对象,并调用了它的MakeSound方法。
13. 委托和事件:
委托是一种类型安全的引用类型,它允许将方法作为参数传递给另一个方法。事件是一种特殊的委托类型,它可以发布一个方法通知。
事件是一种特殊类型的委托,它允许在其他代码中注册方法以响应特定类型的事件。在C#中,可以使用EventHandler委托来定义和使用事件。以下是一个简单的示例,展示了如何创建一个事件并将其绑定到方法:
using System;
class Program
{
public delegate void DoSomethingDelegate();
public event DoSomethingDelegate DoSomethingEvent;
static void Main(string[] args)
{
Program p = new Program();
// 将事件与方法关联
p.DoSomethingEvent += new DoSomethingDelegate(p.DoSomething);
// 触发事件
p.DoSomethingEvent();
Console.ReadKey();
}
public void DoSomething()
{
Console.WriteLine("This is a method for handling 'DoSomething' event.");
}
}
在这个例子中,我们创建了一个名为DoSomething的委托和一个名为DoSomethingEvent的事件。我们使用+=运算符将方法DoSomething与事件DoSomethingEvent关联起来。在Main方法中,我们使用p.DoSomethingEvent触发事件,并输出一条消息。
如果要在事件发生时调用该方法,可以使用以下代码:
p.DoSomethingEvent();
在Program类中,DoSomethingEvent事件在DoSomething方法被调用时触发。这样,就可以在事件发生时调用对应的方法。
14. 匿名方法:
匿名方法是一种在C#中定义函数的简洁方式。匿名方法不需要显式定义函数的返回类型和名称。
匿名方法是在 C# 中,一种在方法中编写方法的方式。它使得我们可以在不使用命名参数的情况下定义一个方法,提高代码的可读性和可重用性。
以下是一个简单的示例,展示如何使用匿名方法实现两个数字的相加操作:
using System;
class Program
{
static void Main(string[] args)
{
int a = 10;
int b = 20;
// 使用匿名方法实现相加
int result = sum(a, b, delegate (int i, int j) {
return i + j;
});
Console.WriteLine("两数之和是: " + result);
}
static int sum(int a, int b, Action<int, int> add)
{
return add(a, b);
}
}
在上面的示例中,我们定义了一个名为 sum 的静态方法,它接收两个参数(数字 a 和 b),并使用一个匿名方法实现两数之和。然后,我们调用此方法,将两个数字 a 和 b 作为参数传递,并将结果打印出来。
请注意,当您使用匿名方法时,它们通常会与其他方法结合使用,以便更好地理解代码的功能。使用匿名方法的另一个优点是,它们使得代码更加简洁,且易于理解和维护。
15. LINQ(Language Integrated Query):
C#中的LINQ(Language Integrated Query)是一种强大的查询技术,可以对数组、集合、数据库等数据源进行查询。LINQ使用from、where、select和join等关键字来构建查询。
PS:可以参考重要工具 LINQPad
还有更多高级主题,如泛型、异步编程、委托、属性、特性等。通过不断实践和学习,日后将逐步熟练掌握C#并编写高质量的代码。