English 中文(简体)
“作为”关键词如何在内部运作?
原标题:
  • 时间:2009-06-05 11:08:15
  •  标签:

我知道这一关键词的功能,但我要知道它是如何在较低级别开展工作的。

哪一个是更快的? 它们是否总是产生同样的结果? 如果是,为什么有两种不同的方式?

// Is there an overhead? An internal try catch?
Class123 obj = someobject as Class123;

if (Class123 != null)
{
    //OK
}

Class123 obj = null;

if (someobject is Class123)
{
    obj = (Class123)someobject;
}
最佳回答

在使用<条码>作为关键词时没有发生内部试捕。 如我所知,这一功能是在汇编者/航天中心建立起来的,因此类型核对是暗含的,是自动化的。

Simple rule:
Use a direct cast when you always expect the object to have a known type (and thus receive a helpful error if it is by chance of the wrong type). Use the as keyword when the object is always of a known type.

之所以存在<条码>作为关键词,纯粹是为了方案人的利益(尽管你正确地指出,尝试捕获物会较慢)。 如你指出:

var castObj = (obj is NewType) ? (NewType)obj : null;

这突出表明,关键词主要是为了简明扼要。

现在,两者之间的绩效差异可能微不足道。 由于类型检查,<条码>()关键词可能略微放缓,但这在绝大多数情况下不可能影响代码。 正如已经说过的那样,过早选择永远不会是明智的事情。 如果你真的希望,基准,但我只想建议使用哪一种方法更方便/更适合你的情况,而不要担心业绩(如果你绝对必须的话)。

问题回答

http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx“rel=“noreferer”>MSDN: as (C# Reference):

运营商喜欢投放作业。 然而,如果不可能进行转换,因为收益无效,而不是提出例外。 考虑以下表述:

expression as type

它相当于以下表述,但仅一次评价这一表述。

expression is type ? (type)expression : (type)null

第一种变量(作为代号) ......

string str1 = strAsObject as string;
if (str1 != null)
{
    this.blabla(str1);
}

......为本《国际刑法》编纂:

L_0009: ldloc.1 
L_000a: isinst string
L_000f: stloc.2 
L_0010: ldloc.2 
L_0011: ldnull 
L_0012: ceq 
L_0014: stloc.s CS$4$0000
L_0016: ldloc.s CS$4$0000
L_0018: brtrue.s L_0024
L_001a: nop 
L_001b: ldarg.0 
L_001c: ldloc.2 
L_001d: call instance void TestWinFormsApplication001.Form1::blabla(string)
L_0022: nop 
L_0023: nop 

......和第二个变量(是指) ......

if (strAsObject is string)
{
    string str2 = (string) strAsObject;
    this.blabla(str2);
}

......为本《国际刑法》编纂:

L_0024: ldloc.1 
L_0025: isinst string
L_002a: ldnull 
L_002b: cgt.un 
L_002d: ldc.i4.0 
L_002e: ceq 
L_0030: stloc.s CS$4$0000
L_0032: ldloc.s CS$4$0000
L_0034: brtrue.s L_0047
L_0036: nop 
L_0037: ldloc.1 
L_0038: castclass string
L_003d: stloc.3 
L_003e: ldarg.0 
L_003f: ldloc.3 
L_0040: call instance void TestWinFormsApplication001.Form1::blabla(string)
L_0045: nop 
L_0046: nop 

页: 1 代码:<代码>L_0038。

简单地确定几个方面:

当你确信物体是你所投的类型时,就应当进行打造。 这种做法可能是无效的(在这种情况下,除非是你重新投下的价值类型,否则将不归还)。

如无法确定,可使用“作为”经营者。 如该物体不能投放,或该物体无效,将退回null

“作为”操作者将IL的专用说明(isinst)译为一种投向cast的类型。 IL 说明,因此,该说明已纳入运行时间。 汇编者简单地介绍了正确的国际空间法研究所声明。

速度可能更快,因为只需要一度在加固时打碎打字,需要两次检查。

这个问题已经得到了很好的回答,但迄今为止,这一问题一直没有足够数目。

Over 100000000 iterations
AS   : Failure  00:00:00.9282403
Cast : Failure  00:00:00.9868966
AS   : Success  00:00:00.9350227
Cast : Success  00:00:01.1382759

这些数字始终如一地回过来。

我想指出,从这些数字中得出的唯一结论是,从业绩的角度来看,选择其中一种方法与另一个“

之后,上述数字大多是有理由的。

“由于”失败的时间比成功要长。 在成功方面没有发生,价值可以像现在一样使用,或者简单复制。 否则,就要求翻一番。

“Cast”在失败时越快,就叫“是”,而且没有做。 成功速度要慢得多,但要求“是”,然后是 cast。

但 我感到惊讶的是,种姓的失败比AS失败要长。

<><>Edit>/strong>

根据要求,在审判/捕获区投放的数字

Over 100000000 iterations
Catch : Failure 05.05:00:00 // approximately, because I didn t hang around
Catch : Success 00:00:01.4000952

编制第一批数字的法典

class Program
{
    const int ITERATION_COUNT = 100000000;
    private static UInt64 stringCount = 0;
    private static UInt64 objectCount = 0;
    static void Main(string[] args)
    {
        Console.WriteLine("Over {0} iterations ", ITERATION_COUNT);

        string s = "Hello";
        object o = new Int32();

        RunTest("AS   : Failure  {0}", TestAs, o);
        RunTest("Cast : Failure  {0}", TestIs_And_Cast, o);
        RunTest("AS   : Success  {0}", TestAs, s);
        RunTest("Cast : Success  {0}", TestIs_And_Cast, s);

        Console.WriteLine("Press any key to stop");
        Console.ReadKey();

    }
    private static void RunTest(string testDescription, Action<object> testToRun, object arg)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < ITERATION_COUNT; i++)
            testToRun(arg);
        sw.Stop();
        Console.WriteLine(testDescription, sw.Elapsed);
    }
    static void TestAs(object obj)
    {
        string s = obj as string;
        if (s != null)
            stringCount++;
        else
            objectCount++;
    }
    static void TestIs_And_Cast(object obj)
    {
        string s = null;
        if (obj is string)
        {
            s = (string)obj;
            stringCount++;
        }
        else
            objectCount++;
    }
}




相关问题
热门标签