-1

Given a very simple expression like:

var x = new Thing(); 

I was thinking, can you encapsulate new Thing as a lambda like () => new Thing() inline, along the lines of:

var x = () => new Thing();

This doesn't compile because I'm trying to assign a delegate to x, not the result of calling it.

But when I try:

var x = (() => new Thing())(); //call my lambda in-line

This also doesn't compile with eror "Method name expected".

So does this imply I cannot declare and use a lambda inline, or just that I don't understand the syntax?

(Note: this is a question about understanding the language, I'm not asking if it's a good idea to do it, only if I can. My example is clearly over-simplified from any real-world use!)

Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • 5
    I don't quite understand why you want to use a lambda. Do you want to replace the whole `GetConnection` method with a lambda? If so, I would definitely advise against that, it'll look horrible. Instead you might want to use a [local function](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions) but the way you extracted it is fine as well. You could also consider adding a parameter to `GetConnection` for the connection-string instead of referencing (presumably) a class variable. – Joelius May 28 '20 at 17:09
  • I'm simply interested to know if you _can_. – Mr. Boy May 28 '20 at 19:38
  • Re-written. Please re-open. – Mr. Boy May 28 '20 at 19:52

1 Answers1

1

using gives you a boundary around IDisposable objects. Once you leave that boundary, the object is destroyed.

For example, take this line

using (var connection = new SqlConnection(connectionString))

SqlConnection implements IDisposable, so once the end of the using block is reached, the disposal method is called.

Now let's look at your example with the lambda -

using (var conn = (() => new SqlConnection(ConnectionString)))

In this case, your variable conn is not a connection, instead it is an anonymous method, which of course does not implement IDisposable. The type of the anonymous method is dependent on the initializer expression, and you don't have one of those. More on that in a moment.

For your second example,

using (var conn = (() => new SqlConnection(ConnectionString))())

This is where I start to get confused about what you are trying to accomplish. I can't tell how you intend this to be different than

using (var conn = new SqlConnection(ConnectionString))

If you absolutely must do that, you would probably need to wrap it in a Func

using (var conn = new Func<SqlConnection>(() => new SqlConnection(ConnectionString)).Invoke())

But, again, I'm not sure why you would want to do this.

Ben Alpert
  • 49
  • 2
  • To understand the language better. I _don't_ intend it to be different . – Mr. Boy May 28 '20 at 19:47
  • On top of what I said, this post may help your understanding as well: https://stackoverflow.com/questions/4965576/why-cant-an-anonymous-method-be-assigned-to-var In your inline example you are actually trying to do some implicit assignment, which is problem one. Problem two is that parentheses have different syntactic meanings in C#, so without an explicit method name, the compiler doesn't know what it's supposed to do there. That's why you would need to use `Func.Invoke()`, but that brings us back to problem one. – Ben Alpert May 28 '20 at 20:19
  • I've substantially rewritten and simplified this to a more abstract question. I think you have already answered it in your final code but perhaps you might edit against the revised question? – Mr. Boy May 29 '20 at 09:44