跳至页脚内容
Iron Academy Logo
学习 C#
学习 C#

其他类别

了解 C# 变量和数据类型

Tim Corey
28m 27s

在 C# 编程中,变量是存储数据值的基础元素。 了解如何有效定义和使用变量对于编写高效、可维护的代码至关重要。 变量可以有不同的类型,包括基本数据类型、常量和动态类型变量,每种类型都有其特定的用途。 此外,类型转换、动态和var关键字为C#编程增加了灵活性和鲁棒性。

Tim Corey 的视频" C# 中的 Dynamic 与 Var "全面概述了这些概念。在本文中,我们将探讨 Tim 讲解的几个主题,包括:

  1. 动态与方差的差异
    • 基本数据类型
    • 变量和常量
  2. 动态自动类型转换
  3. 动态发展的缺点
  4. 为什么以及何时使用动态
  5. 为什么以及何时使用 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 int

Tim在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 safety

Tim 还解释了动态变量缺乏 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对跨语言交互有用,但由于缺乏编译时错误检查和IntelliSense支持,它通常不推荐用于纯C#代码。 他警告说,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 decimal

Tim 强调,明确声明类型可以确保使用正确的类型,尤其是在相似类型之间可能存在混淆的情况下。

然而,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# 学习主题。

Hero Worlddot related to 了解 C# 变量和数据类型
Hero Affiliate related to 了解 C# 变量和数据类型

分享您的所爱,赚取更多收入

您为使用 .NET、C#、Java、Python 或 Node.js 的开发人员创建内容吗?将您的专业知识转化为额外收入!

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我