使用扩展方法进行类型转换是不是一个坏主意

本文关键字:一个 是不是 扩展 方法 类型转换 | 更新日期: 2023-09-27 18:16:10

我最近开始使用WPF,我注意到你必须做很多类型转换(特别是事件)。这是一个美学问题,但我想知道如果我使用扩展方法来强制转换,而不是使用正常的强制转换,那会有多糟糕。

public static T Cast<T>(this object obj)
{
    return (T)obj;
}

这意味着我可以防止一些嵌套的括号,并更改:

Console.WriteLine(((DataGridCell)e.OriginalSource).ActualHeight);

:

Console.WriteLine(e.OriginalSource.Cast<DataGridCell>().ActualHeight);

是否有我可能忽略的明显缺点?当人们在代码中遇到这种情况时,他们会有多反感?:)

使用扩展方法进行类型转换是不是一个坏主意

这与Enumerable.Cast的意图相似,所以我不一定会说人们会反感。

是否有我可能忽略的明显缺点?

主要的缺点是,这将是一个扩展方法,可用于代码中的每个变量,因为您正在扩展System.Object。由于这个原因,我通常避免在Object上使用扩展方法,因为它"污染"了智能感知。

话虽如此,还有其他缺点:

如果在现有的IEnumerable上使用它,则会与Enumerable.Cast<T>发生名称冲突。包含您的名称空间但缺少using System.Linq的文件很容易被其他开发人员误解,因为这与预期的"Cast<T>"扩展方法具有非常不同的含义。

如果在值类型上使用this,则引入了装箱(将值类型压入对象),然后是unbox和强制转换,这实际上会导致强制转换不会发生的异常。如果您这样做,您的扩展方法将引发异常:

int i = 42; 
float f = i.Cast<float>();

这可能是出乎意料的,因为float f = (float)i;是完全合法的。有关详细信息,请参阅Eric Lippert关于代表和身份的帖子。如果你要写这个,我绝对建议你给你的操作符添加一个类约束。

我个人会使用括号。这是一个通用的、语言支持的特性,所有c#开发人员都应该能理解。强制转换具有较短、易于理解和无副作用(在智能感知等方面)的优点。

另一种选择是将其设置为普通的静态方法,允许您这样写:
Console.WriteLine(Utilities.Cast<DataGridCell>(e.OriginalSource).ActualHeight);

这消除了"污染"智能感知的缺点,并使它明显是您编写的方法,但增加了需要使用的键入量。它也不做任何事情来防止装箱和unbox/cast问题。

主要的缺点是类型转换对于每个c#开发人员来说都是众所周知的,而您的Cast<T>方法只是另一个没有发明的方法。下一步,通常是一组扩展,如IsTrue, IsFalse, IsNull等。