C# Enumerable类 之 数据(类型)转换
总目录
前言
在 C# 中,System.Linq.Enumerable 类是 LINQ(Language Integrated Query)的核心组成部分,它提供了一系列静态方法,用于操作实现了 IEnumerable 接口的集合。通过这些方法,我们可以轻松地对集合进行查询、转换、排序和聚合等操作。
本文属于 C# Enumerable类 使用详解 中的一个章节,着重介绍 C# Enumerable 类中数据(类型)转换这部分的内容。
一、概览
方法 | 描述 | 示例 |
---|---|---|
Cast | 数据类型转换 | arrayList.Cast<string>(); |
二、Cast
:数据类型转换
1. 什么是 Cast
Cast
是 LINQ 提供的一个扩展方法,用于将非泛型的 IEnumerable
集合转换为泛型的 IEnumerable<T>
集合,并尝试将集合中的每个元素转换为目标类型 T
。它适用于需要处理非泛型集合(如 ArrayList
)或对象数组的情况。
2. Cast 方法 基本信息
1) Cast
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source);
- 参数:
source
:要转换的源序列。
- 返回值:一个包含转换后结果的新泛型序列
IEnumerable<TResult>
。
2)工作原理
Cast
方法会遍历源序列中的每个元素,并尝试将其转换为目标类型 TResult
。如果某个元素无法成功转换为目标类型,则会抛出 InvalidCastException
异常。因此,在使用 Cast
方法时,确保源序列中的所有元素都可以安全地转换为目标类型是非常重要的。
3)使用场景
- 非泛型集合转换:当需要将非泛型集合(如
ArrayList
)转换为泛型集合时,可以使用Cast
方法。 - 类型转换:在处理对象数组或其他未指定类型的集合时,将每个元素转换为目标类型。
- LINQ 查询:为了使用 LINQ 查询,需要将非泛型集合转换为泛型集合。
3. 使用示例
示例 1:基本用法
假设我们有一个 ArrayList
,我们可以使用 Cast
方法将其转换为 IEnumerable<string>
。
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add("apple");
arrayList.Add("banana");
arrayList.Add("cherry");
var stringEnumerable = arrayList.Cast<string>();
Console.WriteLine(string.Join(",",stringEnumerable));
//输出:apple,banana,cherry
}
}
在这个例子中,我们创建了一个 ArrayList
并添加了一些字符串,然后使用 Cast<string>()
方法将其转换为 IEnumerable<string>
。
示例 2:复杂类型转换
我们可以在 Cast
方法中使用更复杂的类型转换逻辑。例如,将 ArrayList
中的对象转换为自定义类型。
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return $"{Name} ({Age})";
}
}
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(new Person { Name = "Alice", Age = 30 });
arrayList.Add(new Person { Name = "Bob", Age = 25 });
arrayList.Add(new Person { Name = "Charlie", Age = 35 });
var personEnumerable = arrayList.Cast<Person>();
foreach (var person in personEnumerable)
{
Console.WriteLine(person); // 输出: Alice (30) Bob (25) Charlie (35)
}
}
}
在这个例子中,我们将 ArrayList
中的对象转换为 Person
类型,并输出每个人的信息。
示例 3:结合其他 LINQ 方法
Cast
可以与其他 LINQ 方法结合使用,进一步增强其功能。例如,我们可以先使用 Cast
方法将 ArrayList
转换为泛型集合,然后再使用 Where
方法筛选出符合条件的元素。
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return $"{Name} ({Age})";
}
}
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(new Person { Name = "Alice", Age = 30 });
arrayList.Add(new Person { Name = "Bob", Age = 25 });
arrayList.Add(new Person { Name = "Charlie", Age = 35 });
var filteredPersons = arrayList.Cast<Person>()
.Where(p => p.Age >= 30);
foreach (var person in filteredPersons)
{
Console.WriteLine(person); // 输出: Alice (30) Charlie (35)
}
}
}
在这个例子中,我们首先使用 Cast<Person>()
方法将 ArrayList
转换为 IEnumerable<Person>
,然后使用 Where
方法筛选出了年龄大于等于30岁的人。
结合 Select
方法进行转换
有时我们需要在转换的同时对元素进行某种操作。这时可以结合 Cast
和 Select
方法一起使用。
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(1);
arrayList.Add(2);
arrayList.Add(3);
var doubledNumbers = arrayList.Cast<int>()
.Select(n => n * 2);
foreach (var num in doubledNumbers)
{
Console.WriteLine(num); // 输出: 2 4 6
}
}
}
在这个例子中,我们首先使用 Cast<int>()
方法将 ArrayList
转换为 IEnumerable<int>
,然后使用 Select
方法将每个整数乘以2。
示例 4:对象数组转换
Cast
方法也可以用于将对象数组转换为泛型集合。例如,将一个 object[]
数组转换为 IEnumerable<int>
。
class Program
{
static void Main()
{
object[] objects = { 1, 2, 3, 4, 5 };
var intEnumerable = objects.Cast<int>();
Console.WriteLine(string.Join(",",intEnumerable));
// 输出: 1,2,3,4,5
}
}
在这个例子中,我们将一个 object[]
数组转换为 IEnumerable<int>
,并输出每个整数。
示例 5:处理不同类型的元素
如果 ArrayList
或对象数组中包含不同类型的元素,使用 Cast
方法可能会导致 InvalidCastException
异常。为了避免这种情况,可以使用 OfType<T>
方法,它只会转换那些能够成功转换为目标类型的元素。
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(1);
arrayList.Add("two");
arrayList.Add(3);
try
{
var intEnumerable = arrayList.Cast<int>();
foreach (var num in intEnumerable)
{
Console.WriteLine(num);
}
}
catch (InvalidCastException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
var ofTypeIntEnumerable = arrayList.OfType<int>();
foreach (var num in ofTypeIntEnumerable)
{
Console.WriteLine(num); // 输出: 1 3
}
}
}
在这个例子中,我们看到使用 Cast<int>()
方法会导致异常,因为 ArrayList
中包含了不同类型(如 string
)。而使用 OfType<int>()
方法则只会转换那些能够成功转换为 int
的元素。
示例 6:处理接口类型
Cast
方法也可以用于将实现相同接口的元素转换为特定类型的集合。例如,将实现 IAnimal
接口的对象转换为 IEnumerable<Animal>
。
interface IAnimal
{
string Speak();
}
class Dog : IAnimal
{
public string Speak() => "Woof!";
}
class Cat : IAnimal
{
public string Speak() => "Meow!";
}
class Program
{
static void Main()
{
ArrayList arrayList = new ArrayList();
arrayList.Add(new Dog());
arrayList.Add(new Cat());
var animalEnumerable = arrayList.Cast<IAnimal>();
foreach (var animal in animalEnumerable)
{
Console.WriteLine(animal.Speak()); // 输出: Woof! Meow!
}
}
}
在这个例子中,我们将实现 IAnimal
接口的对象转换为 IEnumerable<IAnimal>
,并调用它们的 Speak
方法。
4. 注意事项
尽管 Cast
方法非常有用,但在实际应用中也有一些需要注意的地方:
-
延迟执行:
Cast
方法是惰性执行的,这意味着它不会立即对集合进行转换操作,而是返回一个查询表达式。只有在实际遍历结果集时,才会执行转换操作。这种设计可以提高性能,特别是在处理大型集合时。 -
类型安全性:使用
Cast
方法时,必须确保源集合中的所有元素都可以成功转换为目标类型。否则,程序会在运行时抛出InvalidCastException
异常。为了避免这种情况,可以使用OfType<T>
方法,它只会转换那些能够成功转换为目标类型的元素。 -
不可变性:
Cast
方法不会修改原始集合,而是返回一个新的集合。这意味着原始集合保持不变,新的集合只包含转换后的元素。 -
空集合处理: 如果源集合为空,
Cast
方法将返回一个空的结果集。因此,在使用Cast
方法之前,通常不需要检查集合是否为空。
结语
回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。
参考资料:
微软官方文档 Enumerable