这个运算符在哪里有用?而不是写这个:
Asset a = new Asset();
Stock s = a as Stock; // s is null; no exception thrown
if (s != null) Console.WriteLine (s.SharesOwned);
你最好写一些抛出的东西。我看到了很多
(s!= null)
在生产代码中它真的变得难看。通过这种方式,例外更具描述性和自然性。甚至在概念上:如果不是股票,你如何获得资产?如果它不是股票,它应该是例外。
答案 0 :(得分:4)
你经常会遇到这样的情况:想要抛出异常,因为情况并非例外。您有frob
个对象,您知道可以是Foo
,但也可以是Bar
。因此,只有它是Foo
时,您才想执行某些操作。
您尝试在设计中避免这些情况,而是使用虚拟方法。但有时候,这并没有好办法。
所以,而不是采取迂回的方式,
if (frob is Foo) {
((Foo) frob).Frobnicate();
}
你直接这样做:
var asFoo = frob as Foo;
if (asFoo != null) {
asFoo.Frobnicate();
}
如果没有别的,这至少会更有效率,因为你只需要测试类型相等一次(在as
强制转换中)而不是两次(在{{1}中)并且在演员表中。
作为一个具体示例,当您想要清除表单中的所有输入框时,这非常有用。您可以使用以下代码:
is
在这里使用例外是没有意义的。
答案 1 :(得分:2)
你最好写一些抛出的东西
不一定。用户不喜欢看到扔东西。你应该编写有效的代码。如果没有,你最好通过向用户道歉来妥善处理它。 as
运算符在以下情况下非常有用:例如,您将尝试强制转换,如果此强制转换不起作用,则为变量分配默认值,以便代码继续使用此默认值。这实际上取决于背景。
答案 2 :(得分:2)
as
执行is
,如果is
返回false
则会null
。
听起来像一首歌,但它是答案,我使用它很多,就像在ASP.NET的FindControl方法中一样:
Button myButton = e.item.FindControl("myControlId") as Button;
如果FindControl发现与Button不同的东西,这种赋值不会崩溃或抛出简单赋值null。我非常喜欢这个......
答案 3 :(得分:0)
如果Asset
继承自Stock
,那么这应该没问题。这是我见过这种工作的唯一一种情况,尽管你也可以在接口的情况下使用它。
答案 4 :(得分:0)
是的,as
运算符很有用,是的,它可能被滥用。
如果您确定某个变量x
的类型为T
,则应使用常规广告。
T y = (T)x;
如果T1
和T2
都是变量x
的有效类型,则请谨慎使用as
检查类型和在一次操作中执行演员表。
答案 5 :(得分:0)
您有什么要求?
如果资产是股票打印所拥有的股票数量。
在这种情况下,as
运算符非常有用,但您必须检查stock != null
。这要求暗示了这一点。
打印股票所拥有的股票数量。如果提供了其他资产,则会出错。
然后你应该编写抛出异常的代码。
答案 6 :(得分:0)
例外不是为流量控制而设计的,根据定义,它们是正常事件系列的例外。如果转换失败可以接受,请使用as
。相反,如果不能将“a”作为股票投射永远不会发生,那么你可以使用简单的s=(Stock)a;
来抛出它自己的异常。但是,此时您无法控制异常。
以下内容让开发人员可以更清晰地处理特殊情况:
Asset a= new Asset();
Stock s= a as Stock();
if(s == null) {
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
} else {
// Continue normal flow
}
你可以这样做:
Asset a= new Asset();
try
{
Stock s= (Stock);
// Continue normal flow
}
catch (InvalidCastException exc)
{
// Safely exit from call if possible, maybe make calls to logging mechanism or
// other ways of determining why an exception occurred. Also, could throw custom
// Exception if needed with much more detailed info.
}
然而,这是使用异常作为流量控制,并且成本高且设计糟糕。
答案 7 :(得分:0)
这取决于您的错误处理政策。我在代码库上工作,我们总是使用转换而不是使用as
运算符。但是,在某些情况下,AS运算符非常有用且比异常更快。
例如, 在下面的情况下,你喜欢什么?
public bool Process(int choice)
{
try
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = (SubThing)thing;
}
catch (InvalidCastException ex)
{
// report ex.
return false;
}
}
或
public bool Process(int choice)
{
Thing thing = GetRequiredThing(choice);
SubThing subThing = thing as SubThing;
if (subThing == null)
{
//report error;
return false;
}
}
如果没有必要,您应该始终使用as
运算符。接你的电话。