使用扩展方法进行类型转换是不是一个坏主意
本文关键字:一个 是不是 扩展 方法 类型转换 | 更新日期: 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
等。