2017-2-23 整理
timer
System.Windows.Forms.Timer应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环,Console Application(控制台应用程序)无法使用。
System.Timers.Timer和System.Threading.Timer非常类似,它们是通过.NET Thread Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。
接口
关于接口, 有一个很重要的理念:
提供一个 契约, 实现给定接口的类, 必须提供该接口的所有方法和属性的实现
。 举个例子说明吧, 有个接口 IUser , 其有 age,sex,userName 属性, 有 setUname(),getAge()方法。 有个类,UserClass 继承自 IUser。这时, UserClass 就必须实现 IUser 的所有方法 setUname(),getAge()和所有属性 age,sex,userName。
Assembly
程序集(Assembly)是包涵编译好的,面向.NET Framework 的代码的逻辑单元。
变量
成员变量 回隐式初始化为0, 局部变量(方法中定义的变量)必须显式初始化。 常量 总是静态(static)的, 不必在声明常量时添加 static 关键字。
值类型、引用类型
引用类型在使用的时候需要 new 来实例化一个
;
如果变量是引用类型
, 就可以把其值设置为 null, 表示不指向任何对象。
如果代码对某个非整数值, 如 12.3 硬编码, 则编译器一般假定该变量是 double
,
如果想指定其为 float , 则可以在后面加上字符 f。
若要把数据指定为 decimal 类型的, 只需在数字后面加上 M(或者 m)
String
csharp中,当修改一个str的值时,不是在原来那个string的实例上修改,而是新建了一个string重新赋值
。
break、continue、return
- break 这个关键字我们在上个示例中见到过了, 是用来退出某个 case 语句的。 实际上,
break 也可 以退出 for foreach while 等循环
。 - continue , 和 break 类似, 只是 break 直接跳出了循环, 而 continue 不会跳出循环, 只是该次循环不 执行, 直接执行下次循环。
- return语句一般用于
退出类, 或者方法的
。 如果方法有返回类型, 则 return 语句必须返回这个类型的值。 如果没有返回值, 就直接 return 就可以了。
using namespace
using toolkit = tool ; 这样来引入 命名空间,相当于为toolkit起了一个别名,可以使用tool来访问toolkit里的类。
构造函数
但如果显式的声明了构造函数, 系统就不会自动生成了。我们在实例化类的时候, 就必须以该构造函数而实例化类。
注意, 可以在构造函数中对只读字段赋值, 但不能在其他地方赋值。
结构(struct)在编译时, 编译器总会提供一个无参 的构造函数; 在结构中不允许定义无参的构造函数。
静态构造函数
在 C# 中我们可以给类定义一个无参的静态构造函数( 注意, 必须是无参的), 只要创建类的对象, 该 方法就会执行。
该函数只执行一次, 并且在代码引用类之前执行。
一般, 在类中有一些静态字段或者属性, 需要在第一次使用类之前从外部数据源初始化这些静态字段 和属性, 这时, 我们就采用静态构造函数的方式来解决。
静态构造函数没有访问修饰符, 其他 C#代码也不调用它, 在加载类时, 总是由.NET 运行库调用它。
一 个类只能有一个静态构造函数。
注意, 无参的实例构造函数可以和静态构造函数在类中共存。
因为静态构造函数是在加载类的时候执 行的, 而实例构造函数是在创建实例时执行的, 两者并不冲突。
类
- 抽象类和抽象方法。 C#允许把类声明为 abstract , 抽象类不能实例化, 抽象方法不没有执行代码。 我觉得抽象类和抽象方法没有什么用, 一般我们用接口就可以了。 搞不太明白 C#中这个抽 象类和抽象方法到底想用来干什么。
- 密封类和密封方法。 如果把类声明为 sealed 即标明该类不可以被继承, 如果是方法, 则方法不可以被重写。
装箱、拆箱
装箱就是 将值类型转换为引用类型。 拆箱就是 将引用类型转换为值类型。 比如我们非常常用的 .ToString() 方法, 就是典型的一个装箱的过程。 再如下面的例子 int i=10; object y=(object) i ; //这就是装箱 int x=(int)y; //这是拆箱。
比如 ArrayList arrayListTest=new ArraryList(10); 该句创建了一个大小为 10 的 ArraryList 对象, 当我们再为其添加第 11 项时, 其容量会自动扩大 1 倍, 也就变成了 20, 而原来的对象会被 添加上垃圾收集 器的标记。
wpf AutoCompleteTextBox
WPF的ComboBox其实是一个复杂控件,有一个ToggleButton用来表示下拉按钮,一个Popup用来表示下拉框,在编辑状态(IsEditable=”True”),还会有一个TextBox,所以,如果WPF没有提供一个ComboBox,照道理来说,是很容易自己写一个ComboBox的。 WPF中很多控件都是这样,可能都是使用Primitives命名控件下的控件组合而成。
在WPF中如果自带的自动提示功能有点简单,只要设置3个属性即可:IsEditable,StayOpenOnEdit,IsTextSearchEnabled,而这种自动提示只是简简单单的一个定位功能,很多时候我们要的是筛选,而不是定位。
要实现WPF中ComboBox的自动提示,方式可以有很多,假设咱们不考虑如何去实现对于数据源的筛选,而只是实现界面中当ComboBox的Text改变时,让其筛选,并展示下拉框(Popup)也不是一个简单的事情。
其中一个原因是由于WPF中一个问题:
当设置ComboBox的IsDropDownOpen属性为True时(让ComboBox展开下拉框),TextBox中的文本被全选。
其实WPF中的问题很多,又何止这一个。
当然,正式因为WPF的简单性,才使得这些问题(Bug)都可以自己解决,所以很多东西,其实根本不是问题。
ToXml 序列化对象为Xml格式
可以将一个对象序列化为Xml格式的字符串,保存对象的状态。
public static string ToXml<T>(this T o) where T : new()
{
string retVal;
using (var ms = new MemoryStream())
{
var xs = new XmlSerializer(typeof (T));
xs.Serialize(ms, o);
ms.Flush();
ms.Position = 0;
var sr = new StreamReader(ms);
retVal = sr.ReadToEnd();
}
return retVal;
}
AOP
Aspect-oriented programming In computing, aspect-oriented programming (AOP) is a patented[1] programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code (an advice) without modifying the code itself, instead separately specifying which code is modified via a “pointcut” specification, such as “log all function calls when the function’s name begins with ‘set’”. This allows behaviors that are not central to the business logic (such as logging) to be added to a program without cluttering the code core to the functionality. AOP forms a basis for aspect-oriented software development.
weaving
Weaving refers to the process of injecting functionality into an existing program. This can be done conceptually at a number of levels:
Source code weaving
would inject source code lines before the code is compiledIL weaving (for .NET)
adds the code as IL instructions in the assemblyByteCode weaving (for Java)
works on the class file, see these comments wrt AspectJ
MSIL Injection
https://www.postsharp.net/aop.net/msil-injection
MSIL Injection, or MSIL Insertion
, is the process of modifying the MSIL instructions of an existing method. One says that we inject, or insert new instructions into an existing flow.
System.Data.DataTable (.NET Framework 4)
The DataTable is a central object in the ADO.NET library. Other objects that use the DataTable include the DataSet and the DataView. When accessing DataTable objects they are conditionally case sensitive. If you are creating a DataTable programmatically, you must first define its schema by adding DataColumn objects to the DataColumnCollection. The DataTable also contains a collection of Constraint objects that can be used to ensure the integrity of the data.
typeof
typeof是运算符,获取某一类型的 System.Type 对象。
typeof()的参数只能是int,string,String,自定义类型,且不能是实例。
Type t = typeof(int);
###GetType()方法,获取当前实例的类型。
int i = 10;Console.WriteLine(i.GetType());
###typeof和GetType的联系和区别
Typeof()是运算符而GetType是方法
Typeof()的参数只能是int,string,String,自定义类型,且不能是实例
GetType()是基类System.Object的方法,因此只有建立一个实例之
后才能够被调用(初始化以后)
前者不能实例调用,后者必须实例调用
WPF像素无关性
- 微软之所以称WPF具备“分辨率无关”这一特性,主要是因为WPF的坐标单位设计成为以1/96英寸为一个逻辑像素单位,而不是与设备相关的像素单位。
- WPF无法知道当前使用设备实际的物理DPI为多少,相反通过操作系统的API函数获得操作系统的DPI值,然后简单地认为这就是实际的物理DPI值。【由于操作系统设置为96DPI,因此WPF以为一个实际的像元为1/96英寸】
即假如DPI设置为96,wpf中画一个960长度的线,那么这条线的像素数为:960 *(96/96) = 960像素 即假如DPI设置为120,wpf中画一个960长度的线,那么这条线的像素数为:960 *(120/96) = 1200像素
WPF项目cs-xaml文件不对应
打开csproj文件,修改对应项。
<Compile Include="TheFile.xaml.cs">
<DependentUpon>TheFile.xaml</DependentUpon>
</Compile>
c# 逻辑运算符/二进制与运算
&&、&(||、|) in c#
||
is the logical-or operator, 只能使用bool操作数
|
is the or operator,二进制与运算,操作数可以是任何类型
// The && and || operators are called the conditional logical operators. They are also called the “short-circuiting” logical operators.
// The && and || operators are conditional versions of the & and | operators:
var one = true || bar(); // result is true; bar() is never called(short-circuiting,即如果第一个true,第二个不再计算,&&刚好相反)
var two = true | bar(); // result is true; bar() is always called