表达式树练习实践:C# 五类类运算符的表达式树表达

简介: 表达式树练习实践:C# 五类类运算符的表达式树表达

在 C# 中,算术运算符,有以下类型

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 其他运算符


这些运算符根据参数的多少,可以分作一元运算符、二元运算符、三元运算符。本文将围绕这些运算符,演示如何使用表达式树进行操作。


对于一元运算符和二元运算符的 Expression 的子类型如下:


UnaryExpression; //一元运算表达式
BinaryExpression; //二元运算表达式


一,算术运算符


运算符 描述
+ 把两个操作数相加
- 从第一个操作数中减去第二个操作数
* 把两个操作数相乘
/ 分子除以分母
% 取模运算符,整除后的余数
++ 自增运算符,整数值增加 1
-- 自减运算符,整数值减少 1


+ 与 Add()

正常代码

int a;
            int b;
            a = 100;
            b = 200;
            var ab = a + b;
            Console.WriteLine(ab);


使用表达式树构建

ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // ab = a + b
            BinaryExpression ab = Expression.Add(a, b);
            // 打印 a + b 的值
            MethodCallExpression method = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), ab);
            Expression<Action<int, int>> lambda = Expression.Lambda<Action<int, int>>(method, a, b);
            lambda.Compile()(100, 200);
            Console.ReadKey();


如果想复杂一些,使用 来执行:

ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // 别忘记了赋值
            BinaryExpression aa = Expression.Assign(a, Expression.Constant(100, typeof(int)));
            BinaryExpression bb = Expression.Assign(b, Expression.Constant(200, typeof(int)));
            // ab = a + b
            BinaryExpression ab = Expression.Add(a, b);
            // 打印 a + b 的值
            MethodCallExpression method = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), ab);
            // 以块的形式执行代码,相当于{ }
            // 不需要纠结这里,后面会有详细说明,重点是上面
            var call = Expression.Block(new ParameterExpression[] { a, b }, aa, bb, method);
            Expression<Action> lambda = Expression.Lambda<Action>(call);
            lambda.Compile()();


上面两个示例,是使用表达式树计算结果,然后还是使用表达式树打印结果。

前者依赖外界传入参数值,赋予 a、b,后者则全部使用表达式树赋值和运算。

那么,如何通过表达式树执行运算,获取执行结果呢?


ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // ab = a + b
            BinaryExpression ab = Expression.Add(a, b);
            Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(ab, a, b);
            int result = lambda.Compile()(100, 200);
            Console.WriteLine(result);
            Console.ReadKey();


这些区别在于如何编写 Expression.Lambda()

另外,使用 AddChecked() 可以检查操作溢出。


- 与 Subtract()

与加法一致,此处不再赘述,SubtractChecked() 可以检查溢出。

a - b ,结果是 100 。


ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // ab = a - b
            BinaryExpression ab = Expression.Subtract(a, b);
            Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(ab, a, b);
            int result = lambda.Compile()(200, 100);
            Console.WriteLine(result);


乘除、取模

乘法

// ab = a * b
            BinaryExpression ab = Expression.Multiply(a, b);
// ab = 20000


除法

// ab = a / b
            BinaryExpression ab = Expression.Divide(a, b);
// ab = 2


取模(%)

ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // ab = a % b
            BinaryExpression ab = Expression.Modulo(a, b);
            Expression<Func<int, int, int>> lambda = Expression.Lambda<Func<int, int, int>>(ab, a, b);
            int result = lambda.Compile()(200, 150);
// ab = 50
            Console.WriteLine(result);
            Console.ReadKey();


自增自减

自增自减有两种模型,一种是 x++ 或 x--,另一种是 ++x 或 --x

他们都是属于 UnaryExpression 类型。


算术运算符 表达式树 说明
x++ Expression.PostIncrementAssign() 后置
x-- Expression.PostDecrementAssign() 后置
++x Expression.PreIncrementAssign() 前置
--x Expression.PreDecrementAssign() 前置


巧记:Post 后置, Pre 前置;Increment 是加,Decrement是减;Assign与赋值有关(后面会说到);


x++x-- 的使用

int a = 10;
            int b = 10;
            a++;
            b--;
            Console.WriteLine(a);
            Console.WriteLine(b);


// int a,b;
            ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // a = 10,b = 10;
            BinaryExpression setA = Expression.Assign(a, Expression.Constant(10));
            BinaryExpression setB = Expression.Assign(b, Expression.Constant(10));
            // a++
            UnaryExpression aa = Expression.PostIncrementAssign(a);
            // b--
            UnaryExpression bb = Expression.PostDecrementAssign(b);
            //Console.WriteLine(a);
            //Console.WriteLine(b);
            MethodCallExpression callA = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), a);
            MethodCallExpression callB = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), b);
            BlockExpression block = Expression.Block(
                new ParameterExpression[] { a, b },
                setA,
                setB,
                aa,
                bb,
                callA,
                callB
                );
            Expression<Action> lambda = Expression.Lambda<Action>(block);
            lambda.Compile()();
            Console.ReadKey();


如果想把参数从外面传入,设置 a,b

// int a,b;
            ParameterExpression a = Expression.Variable(typeof(int), "a");
            ParameterExpression b = Expression.Variable(typeof(int), "b");
            // a++
            UnaryExpression aa = Expression.PostIncrementAssign(a);
            // b--
            UnaryExpression bb = Expression.PostDecrementAssign(b);
            //Console.WriteLine(a);
            //Console.WriteLine(b);
            MethodCallExpression callA = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), a);
            MethodCallExpression callB = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), b);
            BlockExpression block = Expression.Block(
                aa,
                bb,
                callA,
                callB
                );
            Expression<Action<int, int>> lambda = Expression.Lambda<Action<int, int>>(block, a, b);
            lambda.Compile()(10, 10);
            Console.ReadKey();


生成的表达式树如下

.Lambda #Lambda1<System.Action`2[System.Int32,System.Int32]>(
    System.Int32 $a,
    System.Int32 $b) {
    .Block() {
        $a++;
        $b--;
        .Call System.Console.WriteLine($a);
        .Call System.Console.WriteLine($b)
    }
}


为了理解一下 Expression.Block(),可以在这里学习一下(后面会说到 Block())。

// int a,b;
            ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            ParameterExpression c = Expression.Variable(typeof(int), "c");
            BinaryExpression SetA = Expression.Assign(a, c);
            BinaryExpression SetB = Expression.Assign(b, c);
            // a++
            UnaryExpression aa = Expression.PostIncrementAssign(a);
            // b--
            UnaryExpression bb = Expression.PostDecrementAssign(b);
            //Console.WriteLine(a);
            //Console.WriteLine(b);
            MethodCallExpression callA = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), a);
            MethodCallExpression callB = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), b);
            BlockExpression block = Expression.Block(
                new ParameterExpression[] { a, b },
                SetA,
                SetB,
                aa,
                bb,
                callA,
                callB
                );
            Expression<Action<int>> lambda = Expression.Lambda<Action<int>>(block, c);
            lambda.Compile()(10);
            Console.ReadKey();


为什么这里要多加一个 c 呢?我们来看看生成的表达式树

.Lambda #Lambda1<System.Action`1[System.Int32]>(System.Int32 $c) {
    .Block(
        System.Int32 $a,
        System.Int32 $b) {
        $a = $c;
        $b = $c;
        $a++;
        $b--;
        .Call System.Console.WriteLine($a);
        .Call System.Console.WriteLine($b)
    }
}


观察一下下面代码生成的表达式树

// int a,b;
            ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // a++
            UnaryExpression aa = Expression.PostIncrementAssign(a);
            // b--
            UnaryExpression bb = Expression.PostDecrementAssign(b);
            //Console.WriteLine(a);
            //Console.WriteLine(b);
            MethodCallExpression callA = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), a);
            MethodCallExpression callB = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), b);
            BlockExpression block = Expression.Block(
                new ParameterExpression[] { a, b },
                aa,
                bb,
                callA,
                callB
                );
            Expression<Action<int, int>> lambda = Expression.Lambda<Action<int, int>>(block, a, b);
            lambda.Compile()(10, 10);
            Console.ReadKey();


.Lambda #Lambda1<System.Action`2[System.Int32,System.Int32]>(
    System.Int32 $a,
    System.Int32 $b) {
    .Block(
        System.Int32 $a,
        System.Int32 $b) {
        $a++;
        $b--;
        .Call System.Console.WriteLine($a);
        .Call System.Console.WriteLine($b)
    }
}


关于前置的自增自减,按照上面示例编写即可,但是需要注意的是, ++x 和 --x ,是“先运算后增/自减”。


二,关系运算符


==、!=、>、<、>=、<=

C# 中的关系运算符如下


运算符 描述
== 检查两个操作数的值是否相等,如果相等则条件为真。
!= 检查两个操作数的值是否相等,如果不相等则条件为真。
> 检查左操作数的值是否大于右操作数的值,如果是则条件为真。
< 检查左操作数的值是否小于右操作数的值,如果是则条件为真。
>= 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。
<= 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。


== 表示相等比较,如果是值类型和 string 类型,则比较值是否相同;如果是引用类型,则比较引用的地址是否相等。

其它的关系运算符则是仅比较值类型的大小。


实例代码

int a = 21;
            int b = 10;
            Console.Write("a == b:");
            Console.WriteLine(a == b);
            Console.Write("a < b :");
            Console.WriteLine(a < b);
            Console.Write("a > b :");
            Console.WriteLine(a > b);
            // 改变 a 和 b 的值 
            a = 5;
            b = 20;
            Console.Write("a <= b:");
            Console.WriteLine(a <= b);
            Console.Write("a >= b:");
            Console.WriteLine(b >= a);
            Console.ReadKey();


使用表达式树实现

// int a,b;
            ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            // a = 21,b = 10;
            BinaryExpression setA = Expression.Assign(a, Expression.Constant(21));
            BinaryExpression setB = Expression.Assign(b, Expression.Constant(20));
            // Console.Write("a == b:");
            // Console.WriteLine(a == b);
            MethodCallExpression call1 = Expression.Call(null,
                typeof(Console).GetMethod("Write", new Type[] { typeof(string) }),
                Expression.Constant("a == b:"));
            MethodCallExpression call11 = Expression.Call(null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.Equal(a, b));
            // Console.Write("a < b :");
            // Console.WriteLine(a < b);
            MethodCallExpression call2 = Expression.Call(null,
                typeof(Console).GetMethod("Write", new Type[] { typeof(string) }),
                Expression.Constant("a < b :"));
            MethodCallExpression call22 = Expression.Call(null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.LessThan(a, b));
            // Console.Write("a > b :");
            // Console.WriteLine(a > b);
            MethodCallExpression call3 = Expression.Call(null,
                typeof(Console).GetMethod("Write", new Type[] { typeof(string) }),
                Expression.Constant("a > b :"));
            MethodCallExpression call33 = Expression.Call(null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.GreaterThan(a, b));
            // 改变 a 和 b 的值 
            // a = 5;
            // b = 20;
            BinaryExpression setAa = Expression.Assign(a, Expression.Constant(5));
            BinaryExpression setBb = Expression.Assign(b, Expression.Constant(20));
            // Console.Write("a <= b:");
            // Console.WriteLine(a <= b);
            MethodCallExpression call4 = Expression.Call(null,
                typeof(Console).GetMethod("Write", new Type[] { typeof(string) }),
                Expression.Constant("a <= b:"));
            MethodCallExpression call44 = Expression.Call(null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.LessThanOrEqual(a, b));
            // Console.Write("a >= b:");
            // Console.WriteLine(b >= a);
            MethodCallExpression call5 = Expression.Call(null,
                typeof(Console).GetMethod("Write", new Type[] { typeof(string) }),
                Expression.Constant("a >= b:"));
            MethodCallExpression call55 = Expression.Call(null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.GreaterThanOrEqual(a, b));
            BlockExpression block = Expression.Block(new ParameterExpression[] { a, b },
                setA,
                setB,
                call1,
                call11,
                call2,
                call22,
                call3,
                call33,
                setAa,
                setBb,
                call4,
                call44,
                call5,
                call55
                );
            Expression<Action> lambda = Expression.Lambda<Action>(block);
            lambda.Compile()();
            Console.ReadKey();


生成的表达式树如下

.Lambda #Lambda1<System.Action>() {
    .Block(
        System.Int32 $a,
        System.Int32 $b) {
        $a = 21;
        $b = 20;
        .Call System.Console.Write("a == b:");
        .Call System.Console.WriteLine($a == $b);
        .Call System.Console.Write("a < b :");
        .Call System.Console.WriteLine($a < $b);
        .Call System.Console.Write("a > b :");
        .Call System.Console.WriteLine($a > $b);
        $a = 5;
        $b = 20;
        .Call System.Console.Write("a <= b:");
        .Call System.Console.WriteLine($a <= $b);
        .Call System.Console.Write("a >= b:");
        .Call System.Console.WriteLine($a >= $b)
    }
}


三,逻辑运算符


&&、||、!


运算符 描述
&& 称为逻辑与运算符。如果两个操作数都非零,则条件为真。
|| 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。
! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。


逻辑运算符的运行,结果是 true 或 false。


逻辑运算符 表达式树
&& Expression.AndAlso()
|| Expression.OrElse()
Expression.Not()


int a = 10;
            int b = 11;
            Console.Write("[a == b && a > b]:");
            Console.WriteLine(a == b && a > b);
            Console.Write("[a > b || a == b]:");
            Console.WriteLine(a > b || a == b);
            Console.Write("[!(a == b)]:");
            Console.WriteLine(!(a == b));
            Console.ReadKey();


使用表达式树编写

//int a = 10;
            //int b = 11;
            ParameterExpression a = Expression.Parameter(typeof(int), "a");
            ParameterExpression b = Expression.Parameter(typeof(int), "b");
            BinaryExpression setA = Expression.Assign(a, Expression.Constant(10));
            BinaryExpression setB = Expression.Assign(b, Expression.Constant(11));
            //Console.Write("[a == b && a > b]:");
            //Console.WriteLine(a == b && a > b);
            MethodCallExpression call1 = Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }), Expression.Constant("[a == b && a > b]:"));
            MethodCallExpression call2 = Expression.Call(
                null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                 Expression.AndAlso(Expression.Equal(a, b), Expression.GreaterThan(a, b))
                );
            //Console.Write("[a > b || a == b]:");
            //Console.WriteLine(a > b || a == b);
            MethodCallExpression call3 = Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }), Expression.Constant("[a > b || a == b]:"));
            MethodCallExpression call4 = Expression.Call(
                null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.OrElse(Expression.Equal(a, b), Expression.GreaterThan(a, b))
                );
            //Console.Write("[!(a == b)]:");
            //Console.WriteLine(!(a == b));
            MethodCallExpression call5 = Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(string) }), Expression.Constant("[!(a == b)]:"));
            MethodCallExpression call6 = Expression.Call(
                null,
                typeof(Console).GetMethod("WriteLine", new Type[] { typeof(bool) }),
                Expression.Not(Expression.Equal(a, b))
                );
            BlockExpression block = Expression.Block(
                new ParameterExpression[] { a, b },
                setA,
                setB,
                call1,
                call2,
                call3,
                call4,
                call5,
                call6
                );
            Expression<Action> lambda = Expression.Lambda<Action>(block);
            lambda.Compile()();
            Console.ReadKey();


生成的表达式树如下

.Lambda #Lambda1<System.Action>() {
    .Block(
        System.Int32 $a,
        System.Int32 $b) {
        $a = 10;
        $b = 11;
        .Call System.Console.Write("[a == b && a > b]:");
        .Call System.Console.WriteLine($a == $b && $a > $b);
        .Call System.Console.Write("[a > b || a == b]:");
        .Call System.Console.WriteLine($a == $b || $a > $b);
        .Call System.Console.Write("[!(a == b)]:");
        .Call System.Console.WriteLine(!($a == $b))
    }
}


四,位运算符


&、|、^、~、<<、>>


运算符 描述 实例
& 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 (A & B) 将得到 12,即为 0000 1100
| 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 (A | B) 将得到 61,即为 0011 1101
^ 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 (A ^ B) 将得到 49,即为 0011 0001
~ 按位取反运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0,包括符号位。 (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。
<< 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 A << 2 将得到 240,即为 1111 0000
>> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 A >> 2 将得到 15,即为 0000 1111


限于篇幅,就写示例了。


位运算符 表达式树
& Expression.Add(Expression left, Expression right)
| Expression.Or(Expression left, Expression right)
^ Expression.ExclusiveOr(Expression expression)
~ Expression.OnesComplement( Expression expression)
<< Expression.LeftShift(Expression left, Expression right)
>> Expression.RightShift(Expression left, Expression right)


五,赋值运算符


运算符 描述 实例
= 简单的赋值运算符,把右边操作数的值赋给左边操作数 C = A + B 将把 A + B 的值赋给 C
+= 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 C += A 相当于 C = C + A
-= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 C -= A 相当于 C = C - A
*= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 C *= A 相当于 C = C * A
/= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 C /= A 相当于 C = C / A
%= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C %= A 相当于 C = C % A
<<= 左移且赋值运算符 C <<= 2 等同于 C = C << 2
>>= 右移且赋值运算符 C >>= 2 等同于 C = C >> 2
&= 按位与且赋值运算符 C &= 2 等同于 C = C & 2
^= 按位异或且赋值运算符 C ^= 2 等同于 C = C ^ 2
|= 按位或且赋值运算符 C |= 2 等同于 C = C | 2


限于篇幅,请自行领略... ...


运算符 表达式树
= Expression.Assign
+= Expression.AddAssign
-= Expression.SubtractAssign
*= Expression.MultiplyAssign
/= Expression.DivideAssign
%= Expression.ModuloAssign
<<= Expression.LeftShiftAssign
>>= Expression.RightShiftAssign
&= Expression.AndAssign
^= Expression.ExclusiveOrAssign
|= Expression.OrAssign


^= ,注意有两种意思一种是位运算符的异或(ExclusiveOrAssign),一种是算术运算符的幂运算(PowerAssign)


六,其他运算符


运算符 描述 实例
sizeof() 返回数据类型的大小。 sizeof(int),将返回 4.
typeof() 返回 class 的类型。 typeof(StreamReader);
& 返回变量的地址。 &a; 将得到变量的实际地址。
* 变量的指针。 *a; 将指向一个变量。
? : 条件表达式 如果条件为真 ? 则为 X : 否则为 Y
is 判断对象是否为某一类型。 If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。
as 强制转换,即使转换失败也不会抛出异常。 Object obj = new StringReader("Hello"); StringReader r = obj as StringReader;


表达式树里面我没有找到这些运算符的如何编写,如果你找到了,欢迎告诉我。。。

相关文章
|
25天前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
2月前
|
存储 C# 索引
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
73 2
|
3月前
|
开发框架 安全 .NET
全面掌握C#中的类型转换:详解与实践
【8月更文挑战第20天】
107 0
|
1天前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
8 3
|
4天前
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
13 1
|
20天前
|
存储 JSON API
HTTP 请求与响应处理:C#中的实践
【10月更文挑战第4天】在现代Web开发中,HTTP协议至关重要,无论构建Web应用还是API开发,都需要熟练掌握HTTP请求与响应处理。本文从C#角度出发,介绍HTTP基础知识,包括请求与响应结构,并通过`HttpClient`库演示如何发送GET请求及处理响应,同时分析常见错误并提供解决方案,助你更高效地完成HTTP相关任务。
64 2
|
24天前
|
数据采集 C# 数据库
数据验证与错误处理:C#中的实践
【10月更文挑战第1天】在软件开发中,数据验证与错误处理至关重要,不仅能提升程序的健壮性和安全性,还能改善用户体验。本文从基础概念入手,详细介绍了C#中的数据验证方法,包括使用自定义属性和静态方法验证数据,以及常见的错误处理技巧,如Try-Catch-Finally结构和自定义异常。通过具体示例,帮助读者掌握最佳实践,构建高质量应用。
57 3
|
24天前
|
C# 开发者
【捞底干货】C#中equals和==运算符的区别
【捞底干货】C#中equals和==运算符的区别
14 1
|
17天前
|
开发框架 缓存 算法
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
开源且实用的C#/.NET编程技巧练习宝库(学习,工作,实践干货)
|
2月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
45 1