了解 C# 变量和数据类型
[[academy-video-youtube({"vid": "UntC0hoeGAQ", "start_time": "0", "title": "理解 C# 变量和数据类型", "creator": "Tim Corey", "length": "28m 27s"})]]
在 C# 编程中,变量是存储数据值的基础元素。 了解如何有效定义和使用变量对于编写高效、可维护的代码至关重要。 变量可以有不同的类型,包括基本数据类型、常量和动态类型变量,每种类型都有其特定的用途。 此外,类型转换、动态和var关键字为C#编程增加了灵活性和鲁棒性。
Tim Corey 的视频" C# 中的 Dynamic 与 Var "全面概述了这些概念。在本文中,我们将探讨 Tim 讲解的几个主题,包括:
- 动态与方差的差异
- 基本数据类型
- 变量和常量
- 动态自动类型转换
- 动态发展的缺点
- 为什么以及何时使用动态
- 为什么以及何时使用 Var
通过 Tim Corey 的解释理解这些概念,您将更深入地了解如何在 C# 中有效地管理和使用变量。
动态与方差的差异
在C#中,var用于隐式类型的局部变量,其类型在编译时确定,确保了类型安全和IntelliSense支持。 相比之下,dynamic允许变量绕过编译时的类型检查,其类型在运行时解析,这提供了更多的灵活性,但也有运行时错误和性能降低的风险。
Tim Corey解释说,dynamic则通过运行时类型解析提供灵活性,这可能导致运行时错误和性能问题。
基本数据类型
Tim 首先在 Visual Studio 中演示 C# 中的基本数据类型。 他创建了一个名为dynamic对象,可以随时赋予新值,其数据类型可以在运行时动态变化。以下代码演示了这一点:
// Declaration of a dynamic variable that can change types at runtime
dynamic testDynamic;// Declaration of a dynamic variable that can change types at runtime
dynamic testDynamic;C# 提供了几种基本数据类型来处理各种类型的数据。 整数类型包括用于32位有符号整数的byte。 对于浮点数,C#提供了用于单精度32位值的decimal,非常适合金融计算。 bool类型用于表示真或假值。 此外,string数据类型表示一系列字符,允许存储和操作文本。
这些数据类型是 C# 编程的基础,能够实现高效的数据存储和操作,正如 Tim 在后续示例中所展示的那样。 可以在一行中声明并赋值整型类型int的多个变量,如果没有显式赋初值,每种数据类型都有一个默认值。 常量变量保持固定值,从而保证代码的一致性。 此外,还可以使用这些数据类型声明实例变量和静态变量,从而确保程序结构稳健灵活。
变量和常量
Tim Corey在1:21尝试创建一个名为var需要一个初始赋值来推断其类型:
// This will result in a compile-time error due to lack of type inference
// var testVar;// This will result in a compile-time error due to lack of type inference
// var testVar;这导致了在testVar下显示一个红色波浪线,指示错误。 在1:55,Tim解释说var需要在声明时指定类型。 例如:
// var assignment with type inference from the initial value
var testVar = 2; // testVar is inferred to be of type int// var assignment with type inference from the initial value
var testVar = 2; // testVar is inferred to be of type intTim在2:44展示,如果他稍后尝试给int:
// Attempting to change the type from int to double causes an error
// testVar = 1.1; // Error: Cannot implicitly convert type 'double' to 'int'// Attempting to change the type from int to double causes an error
// testVar = 1.1; // Error: Cannot implicitly convert type 'double' to 'int'Tim在3:17强调var的类型是在其初始赋值时设置的,之后不能改变。 如果testVar最初被赋值为一个双精度值,它将被推断为双精度:
// Another example with dynamic typing
var testVar = 2.1; // Now testVar is a double// Another example with dynamic typing
var testVar = 2.1; // Now testVar is a double虽然 Tim 没有讨论常量变量,但它们在 C# 程序中同样重要。 在C#中,常量是使用const关键字声明的,后跟常量变量的数据类型和标识符,如:
// Declaring a constant variable
const int MaxValue = 100;// Declaring a constant variable
const int MaxValue = 100;常量必须在声明时赋值,在程序执行期间不能更改,从而为程序逻辑提供不可变值。
动态自动类型转换
Tim强调object但具备更多功能来允许灵活的类型处理。 在3:53, Tim展示了dynamic如何在运行时顺利地在不同类型之间转换,体现了其在不显式转型的情况下处理涉及整数和双精度数的计算能力,如他的代码示例所示:
// Demonstrating dynamic type conversion at runtime
dynamic testDynamic = 1;
testDynamic = testDynamic + 2.1;
Console.WriteLine(testDynamic); // Outputs 3.1 as it converts the integer to a double// Demonstrating dynamic type conversion at runtime
dynamic testDynamic = 1;
testDynamic = testDynamic + 2.1;
Console.WriteLine(testDynamic); // Outputs 3.1 as it converts the integer to a double在这里,Tim在4:39演示testDynamic最初持有一个整数值但在加上2.1之后轻松地转换为双精度值,结果输出3.1。
尽管其具有灵活性,Tim警告不要过度使用dynamic,因为频繁的类型转换会导致性能损失。 他在5:55强调dynamic应在C#开发中谨慎使用,以避免不必要的处理器开销以及丧失编译时类型检查和IntelliSense支持,这对于维护稳健且无错误的代码库至关重要。
发展中动态的缺点
Tim Corey示范dynamic如何导致运行时错误和应用程序中的意外行为。 他首先演示如何声明一个动态变量,并为其分配一个初始空字符串,以避免立即出错。 然后他尝试在动态变量上调用一个不存在的方法dynamic的一个关键缺点:缺乏编译时检查。
// Demonstrating lack of compile-time checks with dynamic
dynamic testDynamic = "";
// testDynamic.sayHi(); // Runtime error: method does not exist// Demonstrating lack of compile-time checks with dynamic
dynamic testDynamic = "";
// testDynamic.sayHi(); // Runtime error: method does not exist此外,在 8:38,Tim 展示了动态变量如何在运行时改变类型,这可能会导致意外行为。 他将一个Person对象赋给了一个动态变量,然后又将其重新赋值为字符串,展示了这种灵活性如何导致逻辑错误并使调试变得困难。
// Demonstrating the potential errors with dynamic type reassignment
dynamic testDynamic = new Person();
testDynamic = "Hi";
Console.WriteLine(testDynamic); // Works fine, but not ideal for type safety// Demonstrating the potential errors with dynamic type reassignment
dynamic testDynamic = new Person();
testDynamic = "Hi";
Console.WriteLine(testDynamic); // Works fine, but not ideal for type safetyTim 还解释了动态变量缺乏 IntelliSense 支持,这可能会导致由于拼写错误或方法名称不正确而导致运行时错误。 例如,在14:05,他调用了一个不存在的属性名Person对象上预期的方法或属性而未在字符串上找到时运行时失败。
// Demonstrating a runtime error due to missing property
// testDynamic.Email = "Test@test.com"; // property not found until runtime// Demonstrating a runtime error due to missing property
// testDynamic.Email = "Test@test.com"; // property not found until runtime使用 Var 关键字的优势
相比之下,var是强类型的,并提供编译时类型检查和IntelliSense支持。 这样可以确保在开发过程中发现任何类型相关的问题,从而使代码更可靠、更易于维护。 Tim Corey通过创建一个Person对象赋给它来演示这一点:
// Using var for strongly-typed assignments
var testVar = new Person();
testVar.FirstName = "Sue";
testVar.LastName = "Storm";
// The use of IntelliSense assists in reducing runtime errors
Console.WriteLine(testVar.SayHello()); // Ideally a method in Person class// Using var for strongly-typed assignments
var testVar = new Person();
testVar.FirstName = "Sue";
testVar.LastName = "Storm";
// The use of IntelliSense assists in reducing runtime errors
Console.WriteLine(testVar.SayHello()); // Ideally a method in Person class尝试调用一个不存在的方法或将var变量重新赋值为不同类型会在编译时被捕获,防止潜在的运行时错误。
// Attempting to change type results in compile-time errors with var
// testVar = "Hi"; // Compile-time error// Attempting to change type results in compile-time errors with var
// testVar = "Hi"; // Compile-time error方法返回类型
在15:05,Tim展示您也可以从方法返回var。 例如:
// Method returning a dynamic type
public dynamic GetMessage() {
return "This is a test";
}// Method returning a dynamic type
public dynamic GetMessage() {
return "This is a test";
}尝试返回var将导致编译时错误,因为方法签名必须指定一个具体的返回类型。
为什么以及何时使用动态
Tim详细说明了dynamic成为必要的特定场景。 他解释说,C# 从根本上来说是一种强类型语言,这意味着每个变量都被赋予一个明确的类型,该类型在其整个生命周期中保持一致。 这与 JavaScript 等语言形成对比,在 JavaScript 中,变量可以动态地改变类型。
Tim 在 18:14 处指出,虽然 C# 是为强类型变量设计的,但在某些情况下,尤其是在与 Python、Ruby 或 COM 对象等外部系统或语言交互时,动态类型可能是有益的。 他用集成Python API的例子来强调dynamic的实际需求。 在这些情况下,拥有一个能够适应来自外部来源的各种数据类型的灵活类型系统,可以简化交互。
Tim Corey在18:44强调虽然dynamic对跨语言交互有用,但一般不推荐用于纯C#代码,因为会丧失编译时错误检查和IntelliSense支持。 他警告dynamic的灵活性会以性能和类型安全为代价,使其对于常规C#编程来说是个不太理想的选择,在这种情况下应优先使用强类型变量。
为什么以及何时使用 Var 关键字
然后Tim讨论了C#中var关键字的使用及其背后的理念。 他指出在使用var时存在两个主要阵营:那些更喜欢仅仅使用它的阵营和那些倾向于显式类型声明的阵营。
Tim在19:43解释,var的支持者认为这鼓励更好的命名约定,使代码自带文档。 他们认为变量名应该具有足够的描述性,无需显式声明即可传达变量类型。
另一方面(20:46),那些喜欢显式类型声明的人认为,直接在代码中看到实际类型可以立即清楚地知道局部变量的类型,而无需将鼠标悬停在变量上查看其类型。 例如:
// Explicit type declaration provides clarity
string firstName = "Tim";// Explicit type declaration provides clarity
string firstName = "Tim";有些人更喜欢这种方法,因为它消除了变量类型的任何歧义。
Tim在21:15分享了他的平衡方法,声明他通常对像decimal。 例如:
// Explicit type ensures there's no ambiguity between float types
double myMoney = 1.1; // This is a double
decimal myMoney = 1.1M; // This is a decimal// Explicit type ensures there's no ambiguity between float types
double myMoney = 1.1; // This is a double
decimal myMoney = 1.1M; // This is a decimalTim 强调,明确声明类型可以确保使用正确的类型,尤其是在相似类型之间可能存在混淆的情况下。
然而,Tim也承认在处理长或复杂类型时,List<List<Person>>可能显得冗长的例子:
// Declaring a complex type using var
var rounds = new List<List<Person>>();// Declaring a complex type using var
var rounds = new List<List<Person>>();他还展示了其在foreach循环中的作用(23:55):
// Utilizing var in loop for cleaner code
foreach (var round in rounds) {
// Do something with each round
}// Utilizing var in loop for cleaner code
foreach (var round in rounds) {
// Do something with each round
}Tim总结说道,虽然var可以减少冗长,但确保变量名清晰且具有描述性以保持可读性并避免混淆是至关重要的。
通过在var与显式类型之间找到平衡,开发者可以编写出清晰、可维护且高效的代码,适当地利用两种方式的优势。
作为匿名对象的变量
Tim讨论在类型不明确或使用匿名类型时使用var。他通过即时创建一个匿名对象来演示这一点,该对象没有预定义类型。 以下是他使用的代码:
// Creating an anonymous object with var
var myItem = new { FirstName = "Tim", Email = "test@test.com" };// Creating an anonymous object with var
var myItem = new { FirstName = "Tim", Email = "test@test.com" };Tim在25:30解释,由于这个对象是匿名的,并且没有特定的类型名称,所以声明它的变量的唯一方式是使用var。 这种方法允许创建和使用对象,而无需定义正式的类。
为了说明这在实践中是如何运作的,蒂姆写道(25:52):
// Outputting properties of an anonymous object
Console.WriteLine($"Hello {myItem.FirstName}: your email is {myItem.Email}");// Outputting properties of an anonymous object
Console.WriteLine($"Hello {myItem.FirstName}: your email is {myItem.Email}");当他在 26 分 25 秒运行代码时,输出结果为:
这说明了var可以处理匿名对象的属性,并且Visual Studio为这些属性提供IntelliSense支持,尽管对象是匿名的。
Tim在26:54澄清他更喜欢对简单和常见类型如string、整数和类实例使用显式类型,因为这能够使代码更清晰。 然而,他在类型长、复杂或不明确时,如在匿名类型或复杂类型声明中,会使用var。
结论
这就是所有内容了——对C#变量和数据类型有清晰的理解,以及策略性地使用dynamic关键字。 通过遵循Tim Corey的平衡方法,您可以确保类型安全和使用dynamic关键字的灵活性。
想要了解更多详细信息,请务必观看 Tim Corey 关于" C# 中的 Dynamic 与 Var "的视频,并访问他的YouTube 频道了解更多 C# 学习主题。




