广告东莞网站建设技术支持,外贸做网站用什么,wordpress微信快速登录,wordpress移动端☺ 观看下文前提#xff1a;如果你的主语言是java#xff0c;现在想再学一门新语言C##xff0c;下文是在java基础上#xff0c;对比和java的不同#xff0c;快速上手C##xff0c;当然不是说学C#的前提是需要java#xff0c;而是下文是从主语言是java的情况下#xff… ☺ 观看下文前提如果你的主语言是java现在想再学一门新语言C#下文是在java基础上对比和java的不同快速上手C#当然不是说学C#的前提是需要java而是下文是从主语言是java的情况下学习C#入门到进阶。 C# 学习参考文档和开发工具 微软c#官方文档https://learn.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/ c# 菜鸟教程https://www.runoob.com/csharp/csharp-tutorial.html 开发工具Visual Studio(VS) C# 概述
C# 概述
C#发音为 “C sharp”是一种新式编程语言不仅面向对象还类型安全。它是由 微软 Microsoft开发的。C# 编程是基于 C 和 C 编程语言的, 源于 C 语言系列 。虽然 C# 的构想十分接近于传统高级语言 C 和 C是一门面向对象的编程语言 但是它与 Java 非常相似 。C# 程序在 .NET 上运行 。C# 文件的后缀为 .cs。 C# 与.Net的关系 C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。C# 程序在 .NET 上运行而 .NET 是名为公共语言运行时 (CLR) 的虚执行系统和一组类库。 CLR 是 Microsoft 对公共语言基础结构 (CLI) 国际标准的实现。.NET是微软公司下的一个开发平台.NET核心就是.NET Framwork.NET框架是.NET程序开发和运行的环境。用 C# 编写的源代码被编译成符合 CLI 规范的中间语言 (IL)。 IL 代码和资源如位图和字符串存储在扩展名通常为 .dll 的程序集中。 程序集包含一个介绍程序集的类型、版本和区域性的清单。通过 C# 生成的 IL 代码可以与通过 .NET 版本的 F#、Visual Basic、C 生成的代码进行交互。 C# 特性 简单现代面向对象类型安全版本控制兼容灵活 简单虽然 C# 的构想十分接近于传统高级语言 C 和 C是一门面向对象的编程语言 但是它与 Java 非常相似 。所以它容易上手 类型安全C# 允许动态分配轻型结构的对象和内嵌存储。 C# 支持泛型方法和类型因此增强了类型安全性和性能。 兼容: C# 有统一类型系统。 所有 C# 类型包括 int 和 double 等基元类型均继承自一个根 object 类型。 所有类型共用一组通用运算。 任何类型的值都可以一致地进行存储、传输和处理。 此外C# 还支持用户定义的引用类型和值类型。 版本控制C# 强调版本控制以确保程序和库以兼容方式随时间推移而变化。 C# 设计中受版本控制加强直接影响的方面包括单独的 virtual 和 override 修饰符关于方法重载决策的规则以及对显式接口成员声明的支持。 C# 流行原因
现代的、通用的编程语言。面向对象。面向组件。容易学习。结构化语言。它产生高效率的程序。它可以在多种计算机平台上编译。.Net 框架的一部分。 C# 一些重要的功能
布尔条件Boolean Conditions自动垃圾回收Automatic Garbage Collection标准库Standard Library组件版本Assembly Versioning属性Properties和事件Events委托Delegates和事件管理Events Management易于使用的泛型Generics索引器Indexers条件编译Conditional Compilation简单的多线程MultithreadingLINQ 和 Lambda 表达式集成 Windows c# 快速入门~C# 和 java 的不同
1、入门demo的hello world
using System;
namespace HelloWorldApplication
{class HelloWorld{static void Main(string[] args){/* 我的第一个 C# 程序*/Console.WriteLine(Hello World);Console.ReadKey();}}
}using 关键字用于在程序中包含 System 命名空间。 一个程序一般有多个 using 语句。 命名空间声明Namespace declaration 最后一行 Console.ReadKey(); 是针对 VS.NET 用户的。这使得程序会等待一个按键的动作防止程序从 Visual Studio .NET 启动时屏幕会快速运行并关闭 ☺ 如果是通过 Visual Studio 写的c# 项目
目录结构 解决方案相当于项目的工程空间工程空间是可以有多个项目的 .vs文件: 是和项目配置相关的 后缀 .sln 文件是解决方案文件通过该文件可以打开解决方案 项目中后缀是 .cs 文件就是咱用 c# 写的代码 ☺ 对于hello world 程序
(1) using
在任何 C# 程序中的第一条语句都是using System;
(2) namespace 2、注释
和java 是一样的~补充关键词 #region 和 #endregion 用来管理注释 3、变量命名规范
除了数字、字母还可以是 4、C# 的变量类型还包含了指针类型
在 C# 中变量分为以下几种类型
值类型Value types引用类型Reference types指针类型Pointer types 引用类型
内置的引用类型有object、dynamic 和 string。 ■ 动态Dynamic类型
您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
声明动态类型的语法dynamic variable_name value;
举例子dynamic d 20; ☺ 字符串String类型还有 修饰有其相对的意义
字符串String类型的值可以通过两种形式进行分配引号和 引号。举例子1使用引号的
String str runoob.com;举例子2使用意义 1取消 \ 在字符串中的转义作用使其单纯的表示为一个‘\’。 2将字符串按照编辑的原格式输出。
string str C:\Windows; //相当于string str C:\\Windows;//作用2使其按照编辑的原格式输出
Console.WriteLine(你好啊
我的朋友);
Console.ReadKey();//输出结果为
你好啊
我的朋友 ■ 指针类型Pointer types C# 中的指针与 C 或 C 中的指针有相同的功能。语法type* identifier; 举例子
char* cptr;
int* iptr;■ 用户自定义引用类型有class、interface 或 delegate。 5、定义常量使用关键词 const 6、占位符的 {数字} Console.WriteLine的后半部的参数变量的顺序就是对应 {0}、{1}、{2}、{3}… 举例子
int n1 10;
int n2 20;
int n3 30;
Console.WriteLine(参数结果是:{0},{1},{2}, n1, n2, n3);
Console.ReadKey();//输出结果为
参数结果是:10,20,307、C# 的运算符和java 不太一样的是它还有其他运算符 对于算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符 和java是一样的 其他运算符:
运算符描述实例is判断对象是否为某一类型。If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。as强制转换即使转换失败也不会抛出异常。Object obj new StringReader(“Hello”); StringReader r obj as StringReader;8、C# 的访问权限-private、protected、internal、protected internal、public 和java有点点不一样的是default 权限在C# 被叫为internal并且c# 多了一个访问权限为protected internal 其他的都是差不多一样的 private、protected、internal、protected internal、public ☺ 9、C# 方法的参数传递ref关键词的使用实现参数作为引用类型out关键字的使用实现参数作为输出类型
c# 方法的定义调用和java 是一模一样的参数的传递和 java 也是一模一样的有三种情况值参数、引用参数、输出参数
☺ 输出参数的作用方法没有返回值时而需要从该方法中返回结果的时候需要使用输出参数 ■ ref 类型的使用实现参数作为引用类型:
using System;
namespace CalculatorApplication
{class NumberManipulator{public void swap(ref int x, ref int y){int temp;temp x; /* 保存 x 的值 */x y; /* 把 y 赋值给 x */y temp; /* 把 temp 赋值给 y */}static void Main(string[] args){NumberManipulator n new NumberManipulator();/* 局部变量定义 */int a 100;int b 200;Console.WriteLine(在交换之前a 的值 {0}, a);Console.WriteLine(在交换之前b 的值 {0}, b);/* 调用函数来交换值 */n.swap(ref a, ref b);//-------这里使用了关键词ref实现了参数作用引用类型--------Console.WriteLine(在交换之后a 的值 {0}, a);Console.WriteLine(在交换之后b 的值 {0}, b);Console.ReadLine();}}
}结果
在交换之前a 的值100 在交换之前b 的值200 在交换之后a 的值100 在交换之后b 的值200 ■ out关键字的使用实现参数作为输出类型
using System;namespace CalculatorApplication
{class NumberManipulator{public void getValue(out int x ){int temp 5;x temp;}static void Main(string[] args){NumberManipulator n new NumberManipulator();/* 局部变量定义 */int a 100;Console.WriteLine(在方法调用之前a 的值 {0}, a);/* 调用函数来获取值 */n.getValue(out a);//-------这里使用了关键词out实现了实现参数作为输出类型--------Console.WriteLine(在方法调用之后a 的值 {0}, a);Console.ReadLine();}}
}结果
在方法调用之前a 的值 100 在方法调用之后a 的值 5 10、不定长参数-关键词 params数组
public 返回类型 方法名称( params 类型名称[] 数组名称 )举例子
using System;namespace ArrayApplication
{class ParamArray{public int AddElements(params int[] arr) //-----------不定长参数----------{int sum 0;foreach (int i in arr){sum i;}return sum;}}class TestClass{static void Main(string[] args){ParamArray app new ParamArray();int sum app.AddElements(512, 720, 250, 567, 889);Console.WriteLine(总和是 {0}, sum);Console.ReadKey();}}
}11、可空类型–单问号 ? 与 双问号 ??
■ 可空类型Nullable Type表示在值类型的正常取值范围内再加上一个null值.
举例子
int i; //默认值0
int? ii; //默认值null可空的int//-----------------------
int? i 3; // 相当于Nullableint i new Nullableint(3);■ 一个和两个的区别
一个问号用于定义值变量是可空的值变量。两个问号用于判断一个可空的变量当前值是否为null若是null则返回指定的值。
a b ?? c //b是一个可空的值变量如果 b 为 null则 a c如果 b 不为 null则 a bdouble? num1 null;
double num3 num1 ?? 5.34; // num1 如果为空值则返回 5.3412、二维数组的写法有点不同 static void Main(string[] args){/* 一个带有 5 行 2 列的数组 */int[,] a new int[5, 2] {{0,0}, {1,2}, {2,4}, {3,6}, {4,8} };int i, j;/* 输出数组中每个元素的值 */for (i 0; i 5; i){for (j 0; j 2; j){Console.WriteLine(a[{0},{1}] {2}, i, j, a[i,j]);}}Console.ReadKey();}■ Array 类的常用方法
Array 类的方法
Array 类的常用属性Length 或 LongLength
序号方法 描述1Clear 根据元素的类型设置数组中某个范围的元素为零、为 false 或者为 null。2Copy(Array, Array, Int32) 从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定。3CopyTo(Array, Int32) 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。4GetLength 获取一个 32 位整数该值表示指定维度的数组中的元素总数。5GetLongLength 获取一个 64 位整数该值表示指定维度的数组中的元素总数。6GetLowerBound 获取数组中指定维度的下界。7GetType 获取当前实例的类型。从对象Object继承。8GetUpperBound 获取数组中指定维度的上界。9GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。10IndexOf(Array, Object) 搜索指定的对象返回整个一维数组中第一次出现的索引。11Reverse(Array) 逆转整个一维数组中元素的顺序。12SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。13Sort(Array) 使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素。14ToString 返回一个表示当前对象的字符串。从对象Object继承。13、c# 中还有结构体在 C# 中的结构与传统的 C 或 C 中的结构不同。
■ 在 C# 中的结构与传统的 C 或 C 中的结构不同
结构可带有方法、字段、索引、属性、运算符方法和事件。结构可定义构造函数但不能定义析构函数。但是您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的且不能被改变。与类不同结构不能继承其他的结构或类。结构不能作为其他结构或类的基础结构。结构可实现一个或多个接口。结构成员不能指定为 abstract、virtual 或 protected。当您使用 New 操作符创建一个结构对象时会调用适当的构造函数来创建结构。与类不同结构可以不使用 New 操作符即可被实例化。如果不使用 New 操作符只有在所有的字段都被初始化之后字段才被赋值对象才被使用。 ■ 类 vs 结构 类是引用类型结构是值类型。 结构不支持继承。 结构不能声明默认的构造函数。 ■ 举例子
//声明 Book 结构
struct Books
{public string title;public string author;public string subject;public int book_id;
};
//使用结构体
public class testStructure
{public static void Main(string[] args){Books Book1; /* 声明 Book1类型为 Books *//* book 1 详述 */Book1.title C Programming;Book1.author Nuha Ali;Book1.subject C Programming Tutorial;Book1.book_id 6495407;/* 打印 Book1 信息 */Console.WriteLine( Book 1 title : {0}, Book1.title);Console.WriteLine(Book 1 author : {0}, Book1.author);Console.WriteLine(Book 1 subject : {0}, Book1.subject);Console.WriteLine(Book 1 book_id :{0}, Book1.book_id);}
}■ 类 vs 结构的使用场景 结构和类的区别 1、结构是值类型它在栈中分配空间而类是引用类型它在堆中分配空间栈中保存的只是引用。2、结构类型直接存储成员数据让其他类的数据位于堆中位于栈中的变量保存的是指向堆中数据对象的引用。 由于结构是值类型并且直接存储数据因此在一个对象的主要成员为数据且数据量不大的情况下使用结构会带来更好的性能。 因为结构是值类型因此在为结构分配内存或者当结构超出了作用域被删除时性能会非常好因为他们将内联或者保存在堆栈中。 ▷ 结构和类的适用场合分析
1、当堆栈的空间很有限且有大量的逻辑对象时创建类要比创建结构好一些2、对于点、矩形和颜色这样的 轻量对象 假如要声明一个含有许多个颜色对象的数组则CLR需要为每个对象分配内存在这种情况下使用结构的成本较低3、在表现抽象和多级别的对象层次时类是最好的选择因为结构不支持继承。4、大多数情况下目标类型只是含有一些数据或者以数据为主。 14、c# 的类和java是一模一样的就是多了个析构函数 c#中的类类的定义-成员变量、成员方法类的构造函数类的实例化、调用类的成员变量、方法都是和java一模一样的 析构函数 析构函数的名称是在类的名称前加上一个波浪形~作为前缀它不返回值也不带任何参数。析构函数用于在结束程序比如关闭文件、释放内存等之前释放资源 。析构函数不能继承或重载。 举例子
using System;
namespace LineApplication
{class Line{private double length; // 线条的长度public Line() // 构造函数{Console.WriteLine(对象已创建);}~Line() //析构函数{Console.WriteLine(对象已删除);}public void setLength( double len ){length len;}public double getLength(){return length;}static void Main(string[] args){Line line new Line();// 设置线条长度line.setLength(6.0);Console.WriteLine(线条的长度 {0}, line.getLength()); }}
}结果
对象已创建 线条的长度 6 对象已删除 15、C# 的继承、实现还有抽象类重写抽象类的方法的写法以及 abstract 和 virtual 的区别(最后总结一下在C#中子类和父类的同名方法的关系)
■ 继承语法
访问修饰符 class 基类
{...
}
class 派生类 : 基类
{...
}子类继承父类语法 class 子类: 父类子类继承父类的构造方法语法
public 子类(参数列表): base(参数列表){}子类调用父类中的普通的方法(非构造方法)语法
子类声明的方法{base.父类声明的方法(参数列表);
}■ 举例子
using System;
namespace InheritanceApplication
{class Shape{public void setWidth(int w){width w;}public void setHeight(int h){height h;}protected int width;protected int height;}// 派生类class Rectangle: Shape{public int getArea(){return (width * height);}}}■ 接口interface实现的语法
//声明为接口使用的关键词还是 interface // 接口 PaintCostpublic interface PaintCost{int getCost(int area);//接口中的方法是没有任何修饰符}//子类实现接口是使用冒号代替java的implements// 派生类class Rectangle : PaintCost{public int getCost(int area){return area * 70;}}▷ 接口接口是可以有属性看但是不能有字段的 // 接口 PaintCost
public interface PaintCost
{int Cost{set; get;}//接口可以有属性属性是特殊的方法属性的特点是通过set设置值通过get获取值//public int cost2; 接口是不能有字段的
}这一块属性的写法属于简写详细的介绍在后边~ ▷ 子类实现接口有两种方式常用的是隐式子类实现接口中声明的方法时用 public显示就是方法前有接口名 接口interface实现的语法的例子就是隐式实现 // 显示实现举例子// 接口 PaintCost
public interface PaintCost
{int getCost(int area);//接口中的方法是没有任何修饰符
}// 派生类
class Rectangle: PaintCost
{int PaintCost.getCost(int area){return area * 70;}
}■ 子类继承抽象类重写抽象类的方法的写法重写abstract修饰的方法要加override
abstract class Shape
{abstract public int area();
}class Rectangle: Shape, PaintCost
{public override int area (){Console.WriteLine(Rectangle 类的面积);return 100;}
}■ abstract 和 virtual 的区别
▷ 区别点 abstract 声明的方法-抽象方法必须存在于抽象类中抽象类中的抽象方法在声明的时候是不可以有实现体的。对于子类继承了抽象类就必须重写人家所有的抽象方法 而 virtual 声明的方法没有要求一定需要存在什么类中可以存在抽象父类、普通父类中并且要求声明为 virtual 方法的同时需要有实现体对于子类继承了父类可以重写或者不重写 父类 virtual 声明的方法。 virtual和abstract 它们有一个共同点如果用来修饰方法前面必须添加public要不然就会出现编译错误虚拟方法或抽象方法是不能私有的。
▷ 举例子
//abstract
abstract class BaseTest1
{public abstract void fun();
}
class DeriveTest1: BaseTest2
{public override void fun() { }//对于子类继承了抽象类就必须重写人家所有的抽象方法}//virtual
class BaseTest2
{public virtual void fun() { }//必须有实现
}
class DeriveTest2: BaseTest1
{//public override void fun() { } //对于子类继承了父类可以重写或者不重写 父类 virtual 声明的方法。
}☺ 最后总结在C#中子类和父类的同名方法的关系C# 细分了重写和覆盖是不同的这里和java 不一样在java中重写就是覆盖覆盖就是重写 ▷重写使用的频率比较高实现多态覆盖用的频率比较低用于对以前无法修改的类进行继承的时候。 ☺ (1) 重写(关键词是override)
重写的意义实现多态性。 多态的意思是父类引用指向子类实例的时候。当子类重写了父类的这个方法。那么父类的引用调用是子类的方法。
//代码中的写法多态的写法
父亲 p new 子类();
//接着调用同名方法
p.sameFunction();
//这时候如果子类中和父类的同名方法没有使用关键词override 进行修饰那么实际上调用的是父类的方法-------------------------------------------------- 举例子-----------------------------------------------
using System;
namespace TestApplication
{public class Shape{public void ordinaryFunction(){Console.WriteLine( Shape中的ordinaryFunction);}}public class Rectangle: Shape{public new void ordinaryFunction()//子类中和父类的同名方法没有使用关键词override 进行修饰即没有重写的作用{Console.WriteLine( Rectangle中的ordinaryFunction);}}class RectangleTester{static void Main(string[] args){Shape s new Rectangle();//Rectangle 没有重写的情况下调用的是父类的方法s.ordinaryFunction();Console.ReadKey();}}
} (2) 覆盖(关键词是new)
覆盖的意义其实就隐藏因为子类中的方法【返回值、参数列表情况都和父类一模一样这就不是重构了本质上子类和父类的这个同名方法是两个不同的方法】覆盖的作用就是直接隐藏掉父类的方法直接调用子类方法。
public class Shape
{public void ordinaryFunction(){Console.WriteLine( Shape中的ordinaryFunction);}
}public class Rectangle : Shape
{public new void ordinaryFunction() //重写基类的同名方法要加上new否则会有警告{Console.WriteLine( Rectangle中的ordinaryFunction);}
}☺ 16、总结 c#的重要的关键词 new、virtual、override、abstract、interface 参考作者-北盟网校B站视频《https://www.bilibili.com/video/BV1xP4y1y783/》下面的文字内容就是作者-北盟网校整个视频所讲的重点了~ ■ new关键字目的是为了隐藏父类同名同参数的方法。不写也可以但会有警告建议写一下。
因为默认就会覆盖子类的方法。覆盖的意思是子类可以调用父类的公开和受保护的方法的。但是万一子类有一个同名同参数的方法这个时候就不再调用父类继承过来的方法而是调用自己的方法。
■ virtual方法和普通方法一样但是加上 virtual 后就允许子类重写 override。
■ override目的就是为了多态。
多态是父类引用指向子类对象调用的是子类的方法体。如果没有 override 那么还是得用父类的方法。多态的实现可以使用 virtualoverride 或者 abstractoverride 或者 接口实现(没有 override) 或者 overrideoverride override 的源头方法 只有两种 virtual和 abstract
■ abstract方法是抽象方法没有方法体抽象方法必须存在抽象类里。
抽象类可以有非抽象方法 和属性 字段等。抽象类是不能 new 的。它的抽象方法没有方法体的。
■ interface接口可以有属性。但是不能有字段。方法也是没有修饰符的。没有方法体。
实现了接口的类的方法不需要用 override 关键字的。 17、C# 命名空间 namespace
和java 的包名作用都是一样了都是为了实现代码的复用。我们知道重用性reusebility是软件工程中一个非常重要的目标。重用不仅仅指自己所写的软件代码、组件等等可以被重复利用更广义的重用是指不同的人不同的团队不同的公司之间可以互相利用别人的成果。另外对于大型软件往往是由多个团队共同开发的这些团队有可能分布于不同的城市、地区、甚至国家。由于这些原因名字管理成为一个非常重要的因素。 C和C# 提供了namespace的概念来支持这种方式。你可以在全局的空间内指定自己的namespace然后还可以在某个namespace内制定更小范围的namespace。 18、预处理
C# 预处理器指令列表
预处理器指令描述#define它用于定义一系列成为符号的字符。#undef它用于取消定义符号。#if它用于测试符号是否为真。#else它用于创建复合条件指令与 #if 一起使用。#elif它用于创建复合条件指令。#endif指定一个条件指令的结束。#line它可以让您修改编译器的行数以及可选地输出错误和警告的文件名。#error它允许从代码的指定位置生成一个错误。#warning它允许从代码的指定位置生成一级警告。#region它可以让您在使用 Visual Studio Code Editor 的大纲特性时指定一个可展开或折叠的代码块。#endregion它标识着 #region 块的结束。预处理器指令指导编译器在实际编译开始之前对信息进行预处理。 所有的预处理器指令都是以 # 开始。且在一行上只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句所以它们不以分号;结束。 C# 编译器没有一个单独的预处理器但是指令被处理时就像是有一个单独的预处理器一样。在 C# 中预处理器指令用于在条件编译中起作用。与 C 和 C 不同的是它们不是用来创建宏。一个预处理器指令必须是该行上的唯一指令。 19、C# 正则表达式
内容更多更复杂些用到再看https://www.runoob.com/csharp/csharp-regular-expressions.html 20、异常
异常处理的关键词和java是一样的都是那几个关键词try、catch、finally 和 throw。不过异常的根类和继承关系有点不同自定义异常的时候要注意一下是应用异常还是系统异常然后再继承该异常类 C# 中的异常类主要是直接或间接地派生于 System.Exception 类。System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。 System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。 System.SystemException 类是所有预定义的系统异常的基类。 21、反射结合了特性一起使用
(1) 优缺点
优点
1、反射提高了程序的灵活性和扩展性。2、降低耦合性提高自适应能力。3、它允许程序创建和控制任何类的对象无需提前硬编码目标类。
缺点
1、性能问题使用反射基本上是一种解释操作 用于字段和方法接入时要远慢于直接代码 。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上普通程序不建议使用。2、使用反射会模糊程序内部逻辑 程序员希望在源代码中看到程序的逻辑反射却绕过了源代码的技术 因而会带来维护的问题反射代码比相应的直接代码更复杂。 (2) 特性
预定义特性Attribute
Net 框架提供了三种预定义特性
AttributeUsageConditionalObsolete
AttributeUsage
▪ 预定义特性 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
▪ 规定该特性的语法如下
[AttributeUsage(validon,AllowMultipleallowmultiple,Inheritedinherited
)]参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。参数 allowmultiple可选的为该特性的 AllowMultiple 属性property提供一个布尔值。如果为 true则该特性是多用的。默认值是 false单用的。参数 inherited可选的为该特性的 Inherited 属性property提供一个布尔值。如果为 true则该特性可被派生类继承。默认值是 false不被继承。
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple true)]22、访问器
get 访问器、set 访问器
// 声明类型为 string 的 Name 属性
public string Name
{get{return name;}set{name value;}
}// 简写为
public string Name {get; set;}举例子
using System;
namespace runoob
{public abstract class Person{public abstract string Name{get; set;}public abstract int Age{get; set;}}class Student : Person{private string name N.A;private int age 0;// 声明类型为 string 的 Name 属性public override string Name{get{return name;}set{name value;}}// 声明类型为 int 的 Age 属性public override int Age{get{return age;}set{age value;}}public override string ToString(){return Name Name , Age Age;}}
}23、委托关键词 delegate
☺ 其实底层就是使用的是反射!
■ 委托类似于 C 或 C 中函数的指针即用变量调方法。好处使方法的使用变得更加灵活。
某个方法自己不调用而将方法自己委托给另一个变量由这个变量执行这个方法执行结果和这个方法自己执行是一样的
■ 委托在实际使用中的例子
自定义排序窗体传值多线程操作
■ 举例子
声明为委托类型语法
public|internal delegate 返回值 委托名(参数列表);对于声明为委托类型的方法是需要使用new 关键词进行实例化创建的然后使用变量进行引用最后通过该变量执行
//声明为委托类型
delegate int NumberChanger(int n);
--------------------------------------------------------------------public static int AddNum(int p){num p;return num;}
--------------------------------------------------------------------
// 使用new 创建委托实例 或者直接使用变量指向方法
NumberChanger nc1 new NumberChanger(AddNum);//相当于 NumberChanger nc1 AddNum;
// 使用委托对象调用方法执行AddNum 方法
nc1(25);■ 委托的多播简单理解理解成java中的链式调用即可
举例子
using System;delegate int NumberChanger(int n);
namespace DelegateAppl
{class TestDelegate{static int num 10;public static int AddNum(int p){num p;return num;}public static int MultNum(int q){num * q;return num;}public static int getNum(){return num;}static void Main(string[] args){// 创建委托实例NumberChanger nc;NumberChanger nc1 new NumberChanger(AddNum);NumberChanger nc2 new NumberChanger(MultNum);nc nc1;nc nc2;// 调用多播nc(5);Console.WriteLine(Value of Num: {0}, getNum());Console.ReadKey();}}
}结果
Value of Num: 75 24、事件【设计模式-发布订阅模式】
(1) 为什么需要事件
原因1
看看前面的委托的声明的语法声明为委托类型的时候修饰符是 public|internal
而有时候程序为了安全考虑需要私有化即封装起来不给外界随意调用随意修改
原因2
委托链可以累加方法 误用了 那么只会执行最后一个的方法不安全有被覆盖的隐患 事件实际上是一个私有委托变量对外界开放了一个向委托变量增加方法绑定的方法和开放了一个减少委托变量身上绑定的方法。 ☺ 官网对事件的概述
事件是一种特殊的多播委托仅可以从声明事件的类或派生类或结构 发布服务器类中对其进行调用。
如果其他类或结构订阅该事件则在发布服务器类引发该事件时将调用其事件处理程序方法。
例子1发布服务器类 event 关键字用于声明发布服务器类中的事件。 //关于如何声明和引发使用 [EventHandler] 作为基础委托类型的事件public class SampleEventArgs
{public SampleEventArgs(string text) { Text text; }public string Text { get; } // readonly
}public class Publisher
{// Declare the delegate (if using non-generic pattern).public delegate void SampleEventHandler(object sender, SampleEventArgs e);// Declare the event.public event SampleEventHandler SampleEvent;// Wrap the event in a protected virtual method// to enable derived classes to raise the event.protected virtual void RaiseSampleEvent(){// Raise the event in a thread-safe manner using the ?. operator.SampleEvent?.Invoke(this, new SampleEventArgs(Hello));}
}例子2就是在例子1的基础上在发布服务器类中添加了监听方法 onXX事件
using System;
namespace ConsoleApplication1
{class Program{static void Main(string[] args){Counter c new Counter(new Random().Next(10));c.ThresholdReached c_ThresholdReached;//真实的事件处理方法for(int i 0; i 10; i){Console.WriteLine(adding one);c.Add(1);}}/*** 真实的事件处理方法*/static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e){Console.WriteLine(The threshold of {0} was reached at {1}., e.Threshold, e.TimeReached);Environment.Exit(0);}}/*** 事件参数类* EventArgs: 是C# 内置的类内部有一个委托属性 public delegate void EventHandlerTEventArgs(object? sender, TEventArgs e);*/public class ThresholdReachedEventArgs : EventArgs{public int Threshold { get; set; }public DateTime TimeReached { get; set; }}class Counter{//声明事件public event EventHandlerThresholdReachedEventArgs ThresholdReached;private int threshold;private int total;public Counter(int passedThreshold){threshold passedThreshold;}public void Add(int x){total x;if (total threshold){ThresholdReachedEventArgs args new ThresholdReachedEventArgs();args.Threshold threshold;args.TimeReached DateTime.Now;OnThresholdReached(args);//监听或通知事件}}/***监听或通知事件*/protected virtual void OnThresholdReached(ThresholdReachedEventArgs e){EventHandlerThresholdReachedEventArgs handler ThresholdReached;if (handler ! null){handler(this, e);//事件处理程序}}}
}(2) 事件的本质 以日志事件为例日志事件写法public event EventHandler LogHandler; 它的的本质如下 private delegate EventHandlerLogHandlerArgs LogHandler;public event EventHandlerLogHandlerArgs LogHandler
{add{LogHandler value;//添加到事件的方法队列中}remove{LogHandler - value;}
}(3) 事件具有以下属性 事件通常用于表示用户操作例如单击按钮或图形用户界面中的菜单选项。 发行者确定何时引发事件订户确定对事件作出何种响应。 一个事件可以有多个订户。 订户可以处理来自多个发行者的多个事件。 没有订户的事件永远也不会引发。 当事件具有多个订户时引发该事件时会同步调用事件处理程序。 在 .NET 类库中事件基于 EventHandler 委托和 EventArgs 基类。 25、C# 不安全代码
当一个代码块使用 unsafe 修饰符标记时C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。
详情https://www.runoob.com/csharp/csharp-unsafe-codes.html 如果本文对你有帮助的话记得给一乐点个赞哦感谢 文章转载自: http://www.morning.hwhnx.cn.gov.cn.hwhnx.cn http://www.morning.gnwpg.cn.gov.cn.gnwpg.cn http://www.morning.gqnll.cn.gov.cn.gqnll.cn http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn http://www.morning.fqcdh.cn.gov.cn.fqcdh.cn http://www.morning.fhbhr.cn.gov.cn.fhbhr.cn http://www.morning.dpdns.cn.gov.cn.dpdns.cn http://www.morning.xldpm.cn.gov.cn.xldpm.cn http://www.morning.gbfck.cn.gov.cn.gbfck.cn http://www.morning.rbkl.cn.gov.cn.rbkl.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.gmplp.cn.gov.cn.gmplp.cn http://www.morning.nfks.cn.gov.cn.nfks.cn http://www.morning.c7493.cn.gov.cn.c7493.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.xbtlt.cn.gov.cn.xbtlt.cn http://www.morning.xtgzp.cn.gov.cn.xtgzp.cn http://www.morning.lqypx.cn.gov.cn.lqypx.cn http://www.morning.dhqzc.cn.gov.cn.dhqzc.cn http://www.morning.gwjqq.cn.gov.cn.gwjqq.cn http://www.morning.pqfbk.cn.gov.cn.pqfbk.cn http://www.morning.btwrj.cn.gov.cn.btwrj.cn http://www.morning.ddzqx.cn.gov.cn.ddzqx.cn http://www.morning.krkwp.cn.gov.cn.krkwp.cn http://www.morning.wxgd.cn.gov.cn.wxgd.cn http://www.morning.fqtzn.cn.gov.cn.fqtzn.cn http://www.morning.pwfwk.cn.gov.cn.pwfwk.cn http://www.morning.rcrnw.cn.gov.cn.rcrnw.cn http://www.morning.rzscb.cn.gov.cn.rzscb.cn http://www.morning.ynlpy.cn.gov.cn.ynlpy.cn http://www.morning.lsjtq.cn.gov.cn.lsjtq.cn http://www.morning.xhklb.cn.gov.cn.xhklb.cn http://www.morning.kpwcx.cn.gov.cn.kpwcx.cn http://www.morning.wmlby.cn.gov.cn.wmlby.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.jlxqx.cn.gov.cn.jlxqx.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.phjny.cn.gov.cn.phjny.cn http://www.morning.tsycr.cn.gov.cn.tsycr.cn http://www.morning.bpzw.cn.gov.cn.bpzw.cn http://www.morning.fqyxb.cn.gov.cn.fqyxb.cn http://www.morning.incmt.com.gov.cn.incmt.com http://www.morning.lfttb.cn.gov.cn.lfttb.cn http://www.morning.dxgt.cn.gov.cn.dxgt.cn http://www.morning.ylkkh.cn.gov.cn.ylkkh.cn http://www.morning.kjfsd.cn.gov.cn.kjfsd.cn http://www.morning.jfcbz.cn.gov.cn.jfcbz.cn http://www.morning.dmsxd.cn.gov.cn.dmsxd.cn http://www.morning.mzgq.cn.gov.cn.mzgq.cn http://www.morning.yfmxn.cn.gov.cn.yfmxn.cn http://www.morning.srsln.cn.gov.cn.srsln.cn http://www.morning.rwcw.cn.gov.cn.rwcw.cn http://www.morning.tdxlj.cn.gov.cn.tdxlj.cn http://www.morning.qkqjz.cn.gov.cn.qkqjz.cn http://www.morning.rrrrsr.com.gov.cn.rrrrsr.com http://www.morning.zcqgf.cn.gov.cn.zcqgf.cn http://www.morning.wrdlf.cn.gov.cn.wrdlf.cn http://www.morning.wdshp.cn.gov.cn.wdshp.cn http://www.morning.rtbhz.cn.gov.cn.rtbhz.cn http://www.morning.pmdlk.cn.gov.cn.pmdlk.cn http://www.morning.txzmy.cn.gov.cn.txzmy.cn http://www.morning.pqcsx.cn.gov.cn.pqcsx.cn http://www.morning.pljdy.cn.gov.cn.pljdy.cn http://www.morning.kpgft.cn.gov.cn.kpgft.cn http://www.morning.kndyz.cn.gov.cn.kndyz.cn http://www.morning.rycbz.cn.gov.cn.rycbz.cn http://www.morning.ntqqm.cn.gov.cn.ntqqm.cn http://www.morning.tngdn.cn.gov.cn.tngdn.cn http://www.morning.tsrg.cn.gov.cn.tsrg.cn http://www.morning.kgjyy.cn.gov.cn.kgjyy.cn http://www.morning.bsrp.cn.gov.cn.bsrp.cn http://www.morning.wtdhm.cn.gov.cn.wtdhm.cn http://www.morning.qrmyd.cn.gov.cn.qrmyd.cn http://www.morning.qtltg.cn.gov.cn.qtltg.cn http://www.morning.xrftt.cn.gov.cn.xrftt.cn http://www.morning.pangucheng.cn.gov.cn.pangucheng.cn http://www.morning.lxngn.cn.gov.cn.lxngn.cn http://www.morning.frfnb.cn.gov.cn.frfnb.cn http://www.morning.bfhrj.cn.gov.cn.bfhrj.cn http://www.morning.yybcx.cn.gov.cn.yybcx.cn