C# 使用扩展方法铸造是个坏主意吗?
我最近开始学习WPF,我注意到你必须做很多的演员(特别是在活动中)。这是一个美学问题,但我想知道如果我使用扩展方法来铸造,而不是使用普通铸造,会有多糟糕C# 使用扩展方法铸造是个坏主意吗?,c#,casting,C#,Casting,我最近开始学习WPF,我注意到你必须做很多的演员(特别是在活动中)。这是一个美学问题,但我想知道如果我使用扩展方法来铸造,而不是使用普通铸造,会有多糟糕 public static T Cast<T>(this object obj) { return (T)obj; } 致: Console.WriteLine(e.OriginalSource.Cast().ActualHeight); 有没有我可能忽略的明显缺点?当人们在代码中遇到这种情况时会有多恶心 这与我的意图相
public static T Cast<T>(this object obj)
{
return (T)obj;
}
致:
Console.WriteLine(e.OriginalSource.Cast().ActualHeight);
有没有我可能忽略的明显缺点?当人们在代码中遇到这种情况时会有多恶心 这与我的意图相似,所以我不一定说人们会厌恶 有没有我可能忽略的明显缺点
主要缺点是,这将是一种可用于代码中每个变量的扩展方法,因为您正在扩展
System.Object
。出于这个原因,我通常避免在对象上使用扩展方法,因为它“污染”了intellisense
尽管如此,还有其他缺点:
如果在现有的IEnumerable
上使用此选项,则会与Enumerable.Cast
发生名称冲突。包含命名空间但缺少使用System.Linq的文件很容易被其他开发人员误解,因为这与预期的“Cast
”扩展方法的含义非常不同
如果在值类型上使用此选项,则会引入装箱(将值类型推入对象),然后是取消装箱和强制转换,这实际上会导致强制转换不会发生的异常。如果执行以下操作,扩展方法将引发异常:
int i = 42;
float f = i.Cast<float>();
这消除了“污染”intellisense的缺点,并且很明显这是您编写的一种方法,但增加了需要使用的键入量。它也无法防止装箱和取消装箱/强制转换问题。主要的缺点是强制转换对于每个C#开发人员来说都是众所周知的,而您的强制转换方法只是另一个没有在这里发明的方法。下一步通常是一组扩展,如IsTrue
,IsFalse
,IsNull
,等等
这是一个语法垃圾。很好,你提到了可枚举的.Cast
:命名自定义扩展方法Cast
意味着缺少使用System.Linq
会导致enumerable.Cast()
在运行时错误编译并严重失败。当然,您可以将方法命名为CastSingle
或其他方法来解决此问题。(我最初认为是,但人们可能会把它与作为操作符混淆。)注意t1.Cast()
然后表示(T2)(object)t1
,而不是(T2)t1
。它们的意思不一样。@hvd是的,这种差异对于值类型来说可能非常糟糕。。。
Console.WriteLine(e.OriginalSource.Cast<DataGridCell>().ActualHeight);
int i = 42;
float f = i.Cast<float>();
Console.WriteLine(Utilities.Cast<DataGridCell>(e.OriginalSource).ActualHeight);