AS运算符在C#中的用处

时间:2011-09-30 12:46:15

标签: c# .net

  

可能重复:
  Direct casting vs 'as' operator?

这个运算符在哪里有用?而不是写这个:

Asset a = new Asset();
Stock s = a as Stock;       // s is null; no exception thrown
if (s != null) Console.WriteLine (s.SharesOwned);

你最好写一些抛出的东西。我看到了很多

  

(s!= null)

在生产代码中它真的变得难看。通过这种方式,例外更具描述性和自然性。甚至在概念上:如果不是股票,你如何获得资产?如果它不是股票,它应该是例外。

8 个答案:

答案 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;

如果T1T2都是变量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运算符。接你的电话。