C # possible erroneous empty statement

In C #, I can write something like:

using (new MyDisposableClass().MethodA()); 

The semicolon triggers a compiler warning, which indicates a possible erroneous empty statement. I do not run the above code, but will this method still not be called?

What uses this type of coding? I saw another topic here, but I ask that there is currently disagreement over the different answers.

thanks

+4
source share
8 answers

this code basically translates to

 MyDisposableClass tmp = new MyDisposableClass().MethodA(); try { } finally { if( tmp != null ) tmp.Dispose(); } 

Basically you delete the result of calling MethodA , and not delete MyDisposableClass , which is the likely intent.

; following the instructions for use is legal, but a warning indicates that you may have added it there by mistake. For example, the following code will not compile:

 using( var tmp = new MyDisposableClass() ); { tmp.MethodA(); } 

The parser evaluates two completely separate blocks and is considered by the compiler as if you typed this:

 using( var tmp = new MyDispoableClass() ) { } { tmp.MethodA(); } 

Easy to miss saggy ; eye, so a compiler warning just suggests that you probably wanted to do something else. There are times when shorter compression is required, and I think the best way to indicate that it is on purpose is to use {} instead ; .

 using( new MyDisposableClass().MethodA() ){} 

Note that this deletion of the result of the MethodA method is not an instance of MyDisposableClass. Your code should be written as

 using( var tmp = new MyDisposableClass() ){ tmp.MethodA(); } 
+11
source

The using statement can be used as an opening for a sentence, at the end of which an object instance is deleted. In other words:

 using (var foo = new bar()) { SomeStatments(); } //foo is disposed 

or

 using (var foo = new bar()) SomeStatments(); //foo is disposed 

Your semicolon does not end the using statement. This actually ends with an empty article following the using statement. This is often not the true intention of programmers. Thus, the compiler generates a warning “possibly erroneous empty statement”.

Refresh . Assuming the code you provided in the question is the actual code, you should probably include MethodA in the static method, as you obviously do not apply the restriction or rely on any members of the class.

+3
source

Why try to be smart?

This should be equivalent, and future developers will not have to specify what might mean stronger syntax.

 //By the name of the example, I can assume that MyDisposableClass //implements IDisposable using (MyDisposableClass something = new MyDisposableClass()) { //Assuming the example code compiles, then the return value of MethodA //implemented IDisposable, too. using(something.MethodA()) { }; } 

And if you need to get rid of something after just one call, why not get MethodA to clear everything you need to clear?

+2
source

I think it would be easier to write this:

 using (var myDisposable = new MyDisposableClass()) { myDisposable.MethodA(); } 

The way you do this, the result of MethodA will actually be seen as an implementation of IDisposable .

+1
source

Maybe this sample helps:

 public static class Helper { public static void Using<T>( Action<T> action ) where T : IDisposable, new() { var obj = new T(); action( obj ); } } // ... Helper.Using<MyDisposableClass>( cls => cls.MethodA() ); Helper.Using<OtherClass>( cls => { for( int i = 0; i < 5; i++ ) { cls.DoRandom(); } } ); 
0
source

You may be tempted to use this style. He calls the method. But at best it’s an idiom and most likely confuses the next reader - including you in a few months, than to enlighten.

Even the replacement ";" with an empty block (which excludes the compiler warning) can lead to scratching the head when reading later - and remember that the code is read more often than it is written.

Paul Alexander answered correctly, but I do not have enough reputation to comment on it.

I used it on the occasion when I was just interested in the side effect of the exception coming from the method:

 try { using (var _ = File.Open(logPath, FileMode.Open, FileAccess.Read)) { } } catch (Exception ex) { ... } 

File.Open returns a FileStream that should be closed or deleted. But I didn’t like it. I ended up calling a variable and putting an explicit Close in the block. I felt that it would be easier to understand later.

0
source

Sometimes compiler warnings are generated and then not cleared when you keep typing. Try creating a solution and see if it goes away.

Also, I'm not sure which comma you are referring to. Do you mean the comma at the end of the line?

-1
source

This method will essentially call MethodA (), and then will never use it. "Use" uses everything that is in parentheses, only inside this specific use block. Then it goes beyond. So:

 using (new MyDisposableClass().MethodA()) { //Code that uses MethodA() } 

... should not give this error, but MethodA () will still be unavailable outside the used block.

Clarification:

You can still call new MyDisposableClass().MethodA() elsewhere in the program, but a specific call made in the code using (new MyDisposableClass().MethodA()) will go out of scope and become inaccessible.

-2
source

Source: https://habr.com/ru/post/1310301/


All Articles