关于C#的测试断言详解
委托:http://www.cnblogs.com/liuhaorain/p/3911845.html
sbyte(8位)
sbyte表示一种整数类型,可以表示大小和存储范围。
从sbyte转换为short,int,long,double,float,decimal都是隐式转换。
不能将一个存储大小更大的非文本数字类型转换给sbyte。
前缀0x或者0X表示十六进制文本, 0b或者0B表示二进制文本,十进制没有前缀.
decimal类型用来表示高精度的浮点数, 可用1M来表示。
varible.GetType() ,typeof(varible)
int n =9;
n.GetType() 等价于 typeof(n) , 获取n的数类型
ReferenceEquals() 比较两个数值型的值
using System;
public class Example
{
public static void Main()
{
int n1 = 12;
int n2 = 82;
long n3 = 12;
Console.WriteLine("n1 and n2 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n2.GetType()));
Console.WriteLine("n1 and n3 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), n3.GetType()));
}
}
// The example displays the following output:
// n1 and n2 are the same type: True
// n1 and n3 are the same type: False
值类型和 引用类型
值类型: 值类型的变量中存储的实际数据,赋值时是编译器把数据复制一份,然后赋给另一个变量
引用类型:引用类型变量中存储的是指向实际数据的引用(真是数据的内存地址),在赋值操作时,和值类型一样,也要进行复制的操作,不过它复制的不是实际数据,而是引用(真实数据的内存地址),所以引用类型在赋值操作时,赋值给另一个变量的是内存地址,这样两个变量中保存的是同一引用,它们的指向完全一样。
例子2:
class MyClass
{
public int val;
}
struct MyStruct
{ public int val; }
class Program
{
static void Main(string[] args)
{
MyClass objectA=new MyClass();
MyClass objectB=objectA; //引用变量的赋值 赋值操作完成后,两个变量都指向同一内存地址
objectA.val=10; //给objectA.val赋值=10 由于objectB和objectA指向同一内存地址,所以ojbectB.val的值也为10
objectB.val=20; //给objectB.val赋值=20 由于objectB和objectA指向同一内存地址,所以objectA.val的值也为20
MyStruct structA=new MyStruct();
MyStruct structB=structA; //结构是值类型 赋值操作完成后,两个结构中的结构信息一致。注意是“结构中的信息”一致。
structA.val=30;
structB.val=40;
Console.WriteLine(objectA.val); //输出结果是20
Console.WriteLine(objectB.val); //输出结果是20
Console.WriteLine(structA.val); //输出结果是30
Console.WriteLine(structB.val); //输出结果是40
Console.ReadLine();
}
}
总结:
- 值类型的变量赋值,只是数据之间的复制
- 引用类型赋值操作,复制的引用,即内存地址,引用类型赋值后 ,二者指向同一个内存地址。如果改变其中一个引用类型变量的值,另一个也会跟着变。
*另一种不同于上面的引用类型,String, 它的特点就是在赋值的时候或者字符串相加操作时,它会在内存中开辟一个新的内存空间来存储操作后的字符串. *
using System;
class Test
{
public static void Main()
{
string s1 = "hello";
string s2 = s1;
Console.WriteLine(s1);
Console.WriteLine(s2);
s1 = "world";
Console.WriteLine(s1);
Console.WriteLine(s2);
}
}
/*
hello
hello
world
hello
*/
解释:
(1) s1 = "hello", 执行的是在堆中创建了一个String类型的对象,然后将这个对象的地址赋值给s1.
(2) s2 = s1, 执行的是将"hello"对象的地址赋值给s2,此时s2和s1是指向的同一个地址;
(3) s1 = "world". 这里编译器将会在内存中重新创建一个String类型的对象,然后将其地址赋值给s1,此时s1将指向新的地址,不再和s2指向相同的地址。所以这里给s1赋值实际上并不会改变"Hello"这个对象,也就是不会改变s2所指向的地址的内容,它改变s1指向的地址(重新分配一个新的地址),而不是它原来指向的对象的内容。
强制类型转换
隐式类型转换: int (32位,4个字节(byte)) 转换到-------> long (64位),float(4byte,32位),double(64),decimal(128,有效位数很大,但是表示的范围比float和double都小) 。
a. 显式类型转换:(int)variable.
- 从long到int的转换,必须显式,否则会产生编译错误。
- 该方式对于float的转换,会失去精度。
- 可以用于object ---> int, 前提是:object的值要被赋予int类型的值,否则会产生编译错误。
注意: 不能用于char 类型到int类型的转换,转后的值会变成ASCII代码,而不是你想要
b. int.Parse(string 类型的变量)
表示把内容是数字的字符串转化为int
该方法只能处理字符串内容,而且字符串的内容只能在int类型可表示的范围之内。
- 如果字符串的内容为null时,则抛出ArgumentNullException异常。
- 如果字符串的内容不是数字,则抛出FormatException异常。
- 如果字符串内容所表示的数字超出int类型可表示的范围,则抛出overflowException异常。
c. int.TryParse( string s, out int result)
该方式也是将数字内容的字符串转化为int类型,但是比int.Parse更优越,它不会抛出异常。如果转换成功,则返回true,转换失败返回false。很明显,最后一个值作为输出值,如果转换失败,输出值为0;如果转换成功,则输出相应的值。
注意: 不能用于char 类型到int类型的转换,转后的值会变成ASCII代码,而不是你想要的。
匿名类型
定义匿名类型
定义一个匿名类型时,需要用到 var 关键字和对象初始化语法。
var : 编译器会在编译时自动生成新类定义(我们无法在C#代码中看到类的名称)。
初始化:它将告诉编译器为新创建的类型创建私有的后台字段和(只读的)属性。
var annonymousTypeInstance = new
{
FirstName = "Bill",
LastName = "Gates"
};
annonymousTypeInstance;.FirstName ; // "Bill";
annonymousTypeInstance.LastName ; // "Gates";
匿名类型本身有许多限制:
- 你并没有控制匿名类型的名称
- 匿名类型继承System.Object
- 匿名类型的字段和属性总是只读的
- 匿名类型不支持事件,自定义方法,自定义操作符和自定义重写
- 匿名类型是隐式封闭的(implicit sealed)
- 匿名类型的实体创建只使用默认构造函数
如果,我们需要快速定义一个实体的形状,而不需要定义其功能时,可以使用匿名类型。
as
用作类型转换,转换不成功时,返回null。
AppendLine()
每次在新的一行添加目标内容,并在末尾加上\r\n
反射 ,及其类Type
DateTime
它是的定义struct类型,所以它是值类型。
ValueType值类型
所有的值类型都是继承至System.ValueType
internal
修饰符,限定的是只是在同一程序集中可访问。
修饰符 Nullable
C#中不允许把null赋值给一个值类型的数据,但是利用Nullable修饰符可可以申明一个可空值类型,可空值类型和普通值类型是一样的,区别就是可以将一个null赋值给它。
Nullable<int> nullableInt = null;
int? nullableInt = null;//int 后面加?表示可空值类型, 是一种特殊的值类型,它的值可以为空。
//用于给变量赋初值的时候,给变量(int类型)赋值为null,而不是0.
int ?? ://用于判断并赋值,先判断当前变量是不是null,如果是就可以赋新值,否则跳过
可空类型Nullable有两个只读属性:
- HasValue , 属于bool类型,只要变量包含非空值,它的值就是true。
- Value , 如果HasValue为true,则说明Value包含有意义的值,那么该变量访问Value属性时,就会返回变量的值;如果HasValue为false, 则访问Value属性将引发
InvaildOperationException
。
yield return
一般情况下,yeild return 会出现在循环遍历中,不适用yeild return时,代码的执行过程是 ,将结果集全部加载到内存中再遍历。
使用yeild return,代码的执行过程是,每调用一个yelid return 所在的循环时,yelid return 就返回一个值回来,是“按需供给“。
yeild return 能保证每次循环遍历的时候都从前一次停止的地方开始,因为编译器会生成一个状态机来保证迭代器的状态。
一个循环遍历中可以有多个 yelid return ,来一次性返回多个值。
一旦执行 yelid break, 后面的代码将不会再执行。
SortedSet<T> 是一个排序的无重复数据的集合。
GetEnumerator()
获取枚举数。
枚举数定位在集合中第一个元素前,在此位置上,Current属于未定义,故在读取current之前,必须调用MoveNext() 将枚举数向前定位到集合的第一个元素,即MoveNext()
将Current设置为下一个元素。
如果MoveNext(0越过集合的末尾,则枚举数将被定位到该集合中最后一个元素的后面,则MoveNext()将返回false。
int[] MyArray = { 10, 11, 12, 13 }; //创建数组
IEnumerator ie = MyArray.GetEnumerator(); //获取枚举数
while (ie.MoveNext()) //移到下一项
Console.WriteLine((int)ie.Current); //获取当前项并输入
枚举数的初始位置是-1,所以要想获取第一个元素就必须执行MoveNext()方法.
上面的代码就是调用枚举数的Current和MoveNext成员函数手工地遍历数组中的元素.
using语句
定义一个范围,在范围结束时处理对象。
使用场景,在某个代码段中使用了类的实例,这个代码段结束时自动执行这个类实例的Dispose方法。
using (Class1 cls1 = new Class1(), cls2 = new Class1())
{
// the code using cls1, cls2
} // call the Dispose on cls1 and cls2
ReferenceEquals()
比较两个对象的引用是否相等,即是指向统一内存地址。
OrderBy()
实现List 升序降序。
var sequence = new[] {4, 2, 1, 3, 5};
List<Student> items = sequence.OrderBy(u => u.Name).ToList();//order by name asc
List<Student> items = sequence.OrderByDescending(u => u.Name).ToList();//order by name desc
Any()
判断序列中的任何元素是否都满足条件,返回bool 值。
var sequence = new[] { 1, 2, 3, 4, 5 };
bool sequenceNotEmpty = sequence.Any();
//true, 判断集合是否为空
//从Any和Count的差别说起.Any() 使用IEnumerator.GetEnumerator() 和 MoveNext() 來判断是否集合为空,而Count()则是返回整个集合的元素个数
bool modThreeNotEmpty = sequence.Any(item => item % 3 == 0);
//true, 是否有一个一个元素满足此条件
Where()
按条件筛选序列中的元素,返回满足条件的元素。
string[] sequence =
{
"a", "quick", "brown", "fox", "jumps", "over", "a", "lazy", "dog"
};
IEnumerable<string> filteredResult = sequence.Where(item => item.Length == 5);
//子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素 ,用作筛选
C#中过滤使用 Where() 扩展
int[] data = { 46, 74, 20, 37, 98, 93, 98, 48, 33, 15 };
int[] result = data.Where(n => n % 3 == 0).ToArray();
注意:Where() 的结果即不是数组也不是 List,需要通过 ToArray() 生成数组,或者通过 ToList() 生成列表。Linq 要在 ToArray() 或者 ToList() 或者其它某些操作的时候才会真正遍历,依次执行 Where() 参数提供的那个筛选函数。
Select()
var sequence = new[]
{
new Name("Edogawa", "Conan"),
new Name("Ogiso", "Setsuna"),
new Name("Kirigaya", "Katsuto")
};
IEnumerable<string> projection = sequence.Select(item => item.ToString());
// {"Edogawa Conan", "Ogiso Setsuna", "Kirigaya Katsuto" };
Take()
取前n个数。
var sequence = new[] {1, 2, 3, 4, 5};
IEnumerable<int> filteredElements = sequence.Take(3);// C#IList取前N行使用Take()方法
// {1, 2, 3};
Skip()
跳过前n个数
var sequence = new[] {1, 2, 3, 4, 5};
IEnumerable<int> filteredElements = sequence.Skip(3);
// { 4, 5};
first()
满足条件的第一个数。
var sequence = new[] { 1, 2, 3, 4, 5 };
int firstElement = sequence.First(); //1
int firstEvenNumber = sequence.First(item => item % 2 ==0); // 2
Last()
满足条件的最后一个数。
var sequence = new[] { 1, 2, 3, 4, 5 };
int lastElement = sequence.Last(); //5
int lastEvenNumber = sequence.Last(item => item % 2 == 0); //4
ElementAt()
第n个下标处的元素。
var sequence = new[] { 1, 2, 3, 4, 5 };
int thirdElement = sequence.ElementAt(2); //3
Count()
int totalNumber = sequence.Count(); // 5, Count 方法如果不带参数,则和 Count 属性一样,和length一样
int numberOfEvenNumbers = sequence.Count(item => item % 2 == 0);//2, 查询为偶数的个数
Min() 求序列的最大值, Max() 求序列的最小值
All()
是否序列中的所有元素都满足条件,返回bool值。
var sequence = new[] { 2, 4, 6, 8, 10 };
bool allEvenNumbers = sequence.All(item => item % 2 == 0); //true
contains() , Concat()
A.contains("b") : A中是否包含某元素b
A.Concat(B) : A和B拼接在一起
Union()求并集, Intersect()求交集, Except()求差集
A.Union(B): 求A和B的并集,并去掉重复元素。
其他类似