这个功能是否存在?在C#中定义自己的花括号

Car*_*los 8 .net c# readability syntactic-sugar

你会欣赏以下两种句法糖:

lock(obj)
{
//Code
}

same as:

Monitor.Enter(obj)
try
{
//Code
}
finally
{
Monitor.Exit(obj)
}
Run Code Online (Sandbox Code Playgroud)

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

same as:

var adapt= new adapter()
try{
//Code2
}
finally{
adapt.Dispose()
}
Run Code Online (Sandbox Code Playgroud)

显然,每种情况下的第一个例子都更具可读性.有没有办法自己定义这种东西,无论是在C#语言中,还是在IDE中?我问的原因是,有很多类似的用法(长篇)可以从中受益,例如.如果您正在使用ReaderWriterLockSlim,那么您需要一些非常相似的东西.

编辑1:

我被要求提供一个例子,所以我会试一试:

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
}
}
Run Code Online (Sandbox Code Playgroud)

当然,您必须考虑如何使用TryEnterReadLocks以及返回的那些东西.但我相信你能想到什么.

Joe*_*orn 19

不完全是,但你可以使用一个动作委托来获得一些东西:

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

        doSomething();
     }
     finally
     {
         //special cleanup
     }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

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
Run Code Online (Sandbox Code Playgroud)

请注意,这有一些限制.例如,在新大括号内不能有有意义的return语句.感谢闭包,你至少仍然可以使用局部变量.


sar*_*ret 5

不幸的是没有.为了支持这一点,c#编译器需要对最终用户更具可扩展性.这将包括能够定义自己的关键字和宏支持等...

但是你可以做的是构建至少有类似感觉的方法,例如:(在用户代码中重新实现lock关键字的一个例子)

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

使用那样会是这样的:

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

public void DoWork()
{....}
Run Code Online (Sandbox Code Playgroud)

要么

lockObject.WithinLock(DoWork);
Run Code Online (Sandbox Code Playgroud)

要么

lockObject.WithinLock(()=>
{
 DoWork();
 //DoOtherStuff
});
Run Code Online (Sandbox Code Playgroud)