简体   繁体   中英

What is the difference between these two method calls in c#?

For example I have some class with one void method in it.

This is my class:

class MyClassTest
{
    public void Print()
    {
        Console.WriteLine("Hello");
    }
}

I am new to classes and little confused, is there a difference between these two method calls?

Here is my main method

static void Main(string[] args)
{
    //first call
    MyClassTest ms = new MyClassTest();
    ms.Print();

    //second call
    new MyClassTest().Print();
}

In the case below you'll want to do this when you want to keep a reference to the constructed object and perform some further operations with it later on.

MyClassTest ms = new MyClassTest();
ms.Print();

Whereas, in the case below you'll only want to do this when you no longer care about the constructed object after construction but are just interested in calling the method Print .

new MyClassTest().Print();

The subtle difference between these two scenarios is that in the case where the object being referenced performs further operations it will most likely get destroyed later than an object that is no longer referenced ie the second example above as the GC (Garbage Collector) will find out that it has no references and therefore decides to get rid of it.

There's no difference, actually. You use the first case when you need to refer to MyTestClass further in your program. You use second case as fire-and-forget . If you plan using second case heavily, it's recommended to make Print method as static .

The IL code shows no difference, except WithInstance method when variable holding reference is loaded onto stack ( stloc.0 and ldloc.0 IL instructions):

MyClassTest ms = new MyClassTest();
ms.Print();

图片1

new MyClassTest().Print();

图片2

Your two calls perform the same semantic operation in c#: the difference is that in your first call, you create the ms variable, which suggests the reader that your intent is to use it again in your code: in fact you are calling ms.Print() after.

Your second call, does not declare any variable, this means that your intent is exactly to call the Print method on a brand new MyClassTest instance only once in your code, and you don't care about the instance your just created.

Side note: when compiling in release mode, the C# compiler will compact and reduce variable usage, therefore your two calls will compile the same and they will be like your second call.

In this particular case, no.

Any time you call a method on a result of another method call, new , property access, etc. as per:

new MyClassTest().Print();

It's akin to if you did:

var temp = new MyClassTest()
temp.Print();

So in this case your two examples are the same.

There are some variants where they differ.

One would be value-type objects that are accessed from array or field access. Here the access might use the address of the actual object rather than making a copy. Now it's possible for the opposite to happen where instead of an implicit temporary local being created and explicit local is removed, but it's not promised. Note that with mutable value-types the code with and without a temporary local are also not semantically the same for these cases (but are for a case closer to your example, where the object is the result of a method call that wasn't a ref return to a ref variable).

Another is when it is inside a yield -using or async method. Here the locals in your method become fields in an object produced (which either implements the IEnumerable<T> and/or IEnumerator<T> for yield or the Task for async ) while the "invisible" temporary locals I described above do not. (The compiler could, and likely will in the future, do a better job at getting rid of some of these that don't exist after yield or async calls and therefore don't really have to be fields, but for the time being all the locals become fields).

So there are a few times when explicit locals with a single operation on them are slightly different to doing the operation directly on the means by which you obtained the value, though your example is not one of those times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM