.NET数据类型之字符串(String)
- 字符串
表示文本,即一系列 Unicode 字符。字符串是 Unicode 字符的有序集合,用于表示文本。 String 对象是 System.Char 对象的有序集合,用于表示字符串。 String 对象的值是该有序集合的内容,并且该值是不可变的(即,为只读)。String 对象的***大小内存中的为 2 GB 或大约 10 亿个字符。
- 关键字
string
- 值范围
一组字符
- 解析数值
- int number = Convert .ToInt32(strNumber);
- 格式化
- 保留2位小数
- bc.FRetailPrice = String.Format("{0:N2}", Convert.ToDecimal(Math.Round(double.Parse(dgvBarcode.Rows[i].Cells["FRetailPrice"].Value.ToString()),2))).ToString();
- 常用方法
- Trim:去除字符串头尾两端的指定字符
- Concat:字符串拼接
- 转义字符
- \' 单引号
- \" 双引号
- \\ 反斜杠
- \0 空
- \a 警告
- \b 退格
- \f 换页
- \n 换行
- \r 回车
- \t 水平制表符
- \v 垂直制表符
- 逐字字符串
字符串加@前缀
- 比较
- 比较空值
- string.IsNullOrEmpty(str1)
- s == string.Empty
- s.Length == 0
- s == ""
- 比较相等性
- 比较空值
使用==和!=操作符进行比较时,引用类型比较的是内存中的对象,但string的相等性操作符被重新定义了,比较的是字符串的值。
- 不可变性
string一旦初始化后不能改变,进行修改后得到的是新的string对象,因此string的滥用是极其的低效。
- StringBuilder
使用StringBuilder对字符串进行修改,修改的是本对象而非产生新对象。
#p#
.NET 数据类型之类(Class)
- 类
类是 C# 中功能最为强大的数据类型。像结构一样,类也定义了数据类型的数据和行为。然后,程序员可以创建作为此类的实例的对象。与结构不同,类支持继承,而继承是面向对象编程的基础部分。
- 构造函数
构造函数是在创建给定类型的对象时执行的类方法,是在运行时调用的而非编译时,包括实例构造函数和静态构造函数。构造函数与类名相同,且不能有返回值。
- 构造函数链
使用this关键字进行串联构造函数调用,可以使用可选参数替代构造函数链,但是可选参数的语法只能在.NET4环境下运行。
- 静态构造函数
-
析构函数(终结器)
析构函数用于析构类的实例,重新对象的Finalize()方法。 不能在结构中定义析构函数。 只能对类使用析构函数。一个类只能有一个析构函数。无法继承或重载析构函数。无法调用析构函数。 它们是被自动调用的。析构函数既没有修饰符,也没有参数,是隐式保护的。
- 关键字
- new:创建新对象
- this:实例对象
- base:基类对象
- static:静态
- 默认访问修饰符
- 类:隐式内部
- 默认构造函数:隐式私有
- 对象
类的实例化,使用new关键字进行实例化
- 对象初始化器
对象初始化器只用少量的代码就可以创建对象并设置一些属性和公共字段,对象初始化时使用{},内部使用逗号分隔的指定值的列表,初始化列表中的每个成员都映射为正在初始化的对象中的公共字段或公共属性。
- 代码示例
- Point p = new Point{X=1,Y=2};
- Object
object 类型在 .NET Framework 中是 Object 的别名。 在 C# 的统一类型系统中,所有类型(预定义类型、用户定义类型、引用类型和值类型)都是直接或间接从 Object 继承的。 可以将任何类型的值赋给 object 类型的变量。
- 装箱
将值类型的变量转换为对象的过程称为“装箱”。
- 拆箱
将对象类型的变量转换为值类型的过程称为“拆箱”。
#p#
.NET 数据类型之指针类型(type*)
- 指针类型
在不安全的上下文中,类型可以是指针类型以及值类型或引用类型。指针类型不继承 object,并且指针类型与 object 之间不存在转换。此外,装箱和取消装箱不支持指针。但是,允许在不同指针类型之间以及指针类型与整型之间进行转换。当在同一个声明中声明多个指针时,* 仅与基础类型一起使用,而不是作为每个指针名称的前缀。 指针不能指向引用或包含引用的结构,因为即使有指针指向对象引用,该对象引用也可能会被执行垃圾回收。GC 并不注意是否有任何类型的指针指向对象。
- 语法
- type* identifier;void* identifier;
- int* p1, p2, p3;
- int number;int* p = &number;
- char* charPointer = stackalloc char[123];for (int i = 65; i < 123; i++){charPointer[i] = (char)i;}
- 指针类型声明
示例 | 说明 |
---|---|
int* p |
p 是指向整数的指针 |
int** p |
p 是指向整数的指针的指针 |
int*[] p |
p 是指向整数的指针的一维数组 |
char* p |
p 是指向字符的指针 |
void* p |
p 是指向未知类型的指针 |
- 指针相关的运算符和语句
运算符/语句 | 用途 |
---|---|
* |
执行指针间接寻址。 |
-> |
通过指针访问结构的成员。 |
[] |
对指针建立索引。 |
& |
获取变量的地址。 |
++ 和 -- |
递增或递减指针。 |
加、减 |
执行指针算法。 |
==、!=、<、>、<= 和 >= |
比较指针。 |
stackalloc |
在堆栈上分配内存。 |
fixed 语句 |
临时固定变量以便可以找到其地址。 |
- 指针转换
- 隐式指针转换
从 | 到 |
---|---|
任何指针类型 |
void* |
null |
任何指针类型 |
-
- 显示指针转换
从 | 到 |
---|---|
任何指针类型 |
所有其他指针类型 |
sbyte、byte、short、ushort、int、uint、long 或 ulong |
任何指针类型 |
任何指针类型 |
sbyte、byte、short、ushort、int、uint、long 或 ulong |
- 代码示例
- 指针访问成员
- truct CoOrds{
- public int x;
- public int y;
- }
- class AccessMembers
- {
- static void Main()
- {
- CoOrds home;
- unsafe
- {
- CoOrds* p = &home;
- p->x = 25;
- p->y = 12;
- System.Console.WriteLine("The coordinates are: x={0}, y={1}", p->x, p->y );
- }
- }
- }
- 指针访问数组元素
- class Pointers
- {
- unsafe static void Main()
- {
- char* charPointer = stackalloc char[123];
- for (int i = 65; i < 123; i++)
- {
- charPointer[i] = (char)i;
- }
- System.Console.WriteLine("Uppercase letters:");
- for (int i = 65; i < 91; i++)
- {
- System.Console.Write(charPointer[i]);
- }
- System.Console.WriteLine();
- System.Console.WriteLine("Lowercase letters:");
- for (int i = 97; i < 123; i++)
- {
- System.Console.Write(charPointer[i]);
- }
- }
- }
- class TestCopy
- {
- static unsafe void Copy(byte[] src, int srcIndex, byte[] dst, int dstIndex, int count)
- {
- if (src == null || srcIndex < 0 ||
- dst == null || dstIndex < 0 || count < 0)
- {
- throw new System.ArgumentException();
- }
- int srcsrcLen = src.Length;
- int dstdstLen = dst.Length;
- if (srcLen - srcIndex < count || dstLen - dstIndex < count)
- {
- throw new System.ArgumentException();
- }
- fixed (byte* pSrc = src, pDst = dst)
- {
- byte* ps = pSrc;
- byte* pd = pDst;
- for (int i = 0 ; i < count / 4 ; i++)
- {
- *((int*)pd) = *((int*)ps);
- pd += 4;
- ps += 4;
- }
- for (int i = 0; i < count % 4 ; i++)
- {
- *pd = *ps;
- pd++;
- ps++;
- }
- }
- }
- static void Main()
- {
- byte[] a = new byte[100];
- byte[] b = new byte[100];
- for (int i = 0; i < 100; ++i)
- {
- a[i] = (byte)i;
- }
- Copy(a, 0, b, 0, 100);
- System.Console.WriteLine("The first 10 elements are:");
- for (int i = 0; i < 10; ++i)
- {
- System.Console.Write(b[i] + " ");
- }
- System.Console.WriteLine("\n");
- }
- }
#p#
.NET 数据类型之动态类型(Dynamic)
- Dynamic
- 代码示例
-
- 在声明中,作为属性、字段、索引器、参数、返回值或类型约束的类型。 下面的类定义在几个不同的声明中使用 dynamic。
- class ExampleClass
- {
- static dynamic field;
- dynamic prop { get; set; }
- public dynamic exampleMethod(dynamic d)
- {
- dynamic local = "Local variable";
- int two = 2;
- if (d is int)
- {
- return local;
- }
- else
- {
- return two;
- }
- }
- }
在显式类型转换中,作为转换的目标类型。
- static void convertToDynamic()
- {
- dynamic d;
- int i = 20;
- d = (dynamic)i;
- Console.WriteLine(d);
- string s = "Example string.";
- d = (dynamic)s;
- Console.WriteLine(d);
- DateTime dt = DateTime.Today;
- d = (dynamic)dt;
- Console.WriteLine(d);
- }
在以类型充当值(如 is 运算符或 as 运算符右侧)或者作为 typeof 的参数成为构造类型的一部分的任何上下文中。 例如,可以在下列表达式中使用 dynamic。
- int i = 8; dynamic d; d = i as dynamic; Console.WriteLine(typeof(List<dynamic>));
#p#
.NET 数据类型之匿名类型(var)
- 匿名类型
匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。 类型名由编译器生成,并且不能在源代码级使用。 每个属性的类型由编译器推断。
可通过使用 new 运算符和对象初始值创建匿名类型。
- 限制条件
- 没有控制匿名类型的名字
- 匿名类型继承自Object
- 匿名类型的字段和属性总是只读的
- 匿名类型不支持事件、自定义方法、自定义操作符和自定义重写
- 匿名类型是隐式封闭的
- 匿名类型的实例创建只使用默认构造函数
- 语法
- var v = new { Amount = 108, Message = "Hello" };
- var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};
- var productQuery =
- from prod in products
- select new { prod.Color, prod.Price };
- foreach (var v in productQuery)
- {
- Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
- }