Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does this feature exist? Defining my own curly brackets in C#

You'll appreciate the following two syntactic sugars:

lock(obj)
{
//Code
}

same as:

Monitor.Enter(obj)
try
{
//Code
}
finally
{
Monitor.Exit(obj)
}

and

using(var adapt = new adapter()){
//Code2
}

same as:

var adapt= new adapter()
try{
//Code2
}
finally{
adapt.Dispose()
}

Clearly the first example in each case is more readable. Is there a way to define this kind of thing myself, either in the C# language, or in the IDE? The reason I ask is that there are many similar usages (of the long kind) that would benefit from this, eg. if you're using ReaderWriterLockSlim, you want something pretty similar.

EDIT 1:

I've been asked to provide an example, so I'll give it a go:

myclass
{
ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();

void MyConcurrentMethod()
{
  rwl.EnterReadLock();
  try{
    //Code to do in the lock, often just one line, but now its turned into 8!
  }
  finally
  {
    rwl.ExitReadLock();
  }
}
}

//I'd rather have:
void MyConcurrentMethod()
{
rwl.EnterReadLock()
{
   //Code block. Or even simpler, no brackets like one-line ifs and usings
}
}

Of course you'd have to give some thoughts as to how to use the TryEnterReadLocks and those kinds of things with returns. But I'm sure you could think of something.

like image 830
Carlos Avatar asked May 21 '10 14:05

Carlos


People also ask

How do you write curly braces in C?

In programming, curly braces (the { and } characters) are used in a variety of ways. In C/C++, they are used to signify the start and end of a series of statements. In the following expression, everything between the { and } are executed if the variable mouseDOWNinText is true. See event loop.

Does C use curly brackets?

Curly braces (also referred to as just “braces” or as “curly brackets”) are a major part of the C and C++ programming languages.

What is the function curly bracket in programming?

Different programming languages have various ways to delineate the start and end points of a programming structure, such as a loop, method or conditional statement. For example, Java and C++ are often referred to as curly brace languages because curly braces are used to define the start and end of a code block.

What is curly bracket syntax?

curly-bracket language (plural curly-bracket languages) (programming) A programming language whose syntax uses curly brackets to enclose blocks, such as C, C++, Java, or C#.


Video Answer


3 Answers

Not exactly, but you can use an action delegate to get something close:

void MyBrace(Action doSomething)
{      
     try
     {
        //wait for lock first

        doSomething();
     }
     finally
     {
         //special cleanup
     }
}

And use it like this:

MyBrace(() => 
{
   //your code goes here, but won't run until the lock is obtained
});  // cleanup will always run, even if your code throws an exception

Note that there are some limitations with this. You can't have a meaningful return statement inside the new braces, for example. Thanks to closures you will at least still be able to use local variables.

like image 188
Joel Coehoorn Avatar answered Sep 20 '22 12:09

Joel Coehoorn


Unfortuanetly not. In order to support this the c# compiler would need to be more extensible for the end user. This would include being able to define your own keywords and have macro support etc...

However what you can do is build methods that at least have a bit of a similar feel such as this: (contrieved example of reimplementing lock keyword in user code)

public static class MyLocker
{
 public static void WithinLock(this object syncLock, Action action)
 {
  Monitor.Enter(syncLock)
  try
  {
   action();
  }
  finally
  {
   Monitor.Exit(syncLock)
  }
 }
}

using then would be like this:

object lockObject = new object();
MyLocker.WithinLock(lockObject, DoWork);

public void DoWork()
{....}

OR

lockObject.WithinLock(DoWork);

OR

lockObject.WithinLock(()=>
{
 DoWork();
 //DoOtherStuff
});
like image 40
saret Avatar answered Sep 18 '22 12:09

saret


You can't define constructs like this directly, but there are ways to create similar concise patterns:

You can define classes that implement IDisposable to encapsulate this sort of block usage semantics. For instance, if you had some class that encapsulated acquiring a ReaderWriterLockSlim (acquire on construct, release on Dispose) read lock, you could create a property on your class that constructs the instance, which results in a syntax like this:

using (this.ReadLock) // This constructs a new ReadLockHelper class, which acquires read lock
{
   //Do stuff here....
}
//After the using, the lock has been released.

This is arguably an abuse of IDisposable, but this pattern has definitely been used in production code.

You can use Aspect-oriented programming (with tools like PostSharp) to wrap a method body with reusable entry/exit logic. This is often used to inject logging or other cross-cutting concerns that you'd like to apply to your code without cluttering it up.

You can write functions that take delegates as parameters, which then wrap up the delegated logic in some similar structure. For instance, for the ReaderWriterLockSlim again, you can create a method like this:

private void InReadLock(Action action)
{
   //Acquires the lock and executes action within the lock context
} 

This can be quite powerful, as the support for lambda expression with closures allows for arbitrarily complex logic without manually creating wrapper functions and passing required parameters in fields.

like image 35
Dan Bryant Avatar answered Sep 20 '22 12:09

Dan Bryant