我想编写自己的自定义复合语句,它们具有类似的机制using和lock机制,它们在编译之前在语句块的开头和结尾注入代码.
我一直在尝试寻找可能提出类似问题的问题,但我无法正确地弄清楚这种"代码范围"被称为什么,除了文档说这些是复合语句.
我知道"锁定"和"使用"是关键字.我不想拥有自己的关键字,因为我知道这是不可能的.
我不确定在c#中是否可以这样做,例如:
而不是做:
StartContext(8);
//make method calls
EndContext();
Run Code Online (Sandbox Code Playgroud)
这可以减少到:
DoSomethingInContext(8) {
//make method calls
}
Run Code Online (Sandbox Code Playgroud)
当然,这不一定只是一个单行调用.encapuslated代码的开头和结尾可以是由自定义复合语句插入的多行代码.
您可以稍微重写代码:
DoSomethingInContext(8, () => {
// make method calls
});
Run Code Online (Sandbox Code Playgroud)
您的方法的签名将是这样的:
public void DoSomethingInContext(int contextId, Action contextBoundAction)
{
// start/open/enter context
try
{
contextBoundAction();
}
finally
{
// stop/close/exit context
}
}
Run Code Online (Sandbox Code Playgroud)
需要注意的一件事是,因为这里有一个替代的答案IDisposable,就是这个基于委托的语法可以在Visual Studio和ReSharper的各种(较旧)版本中进行智能感知有点不可思议.有时它会尝试帮助您填写参数,以便DoSomethingInContext在您真正希望它帮助您填写委托内的方法调用中的参数时.对于其他IDE,例如较旧的Xamarin工作室也是如此,这些IDE在嵌套委托方面存在严重的性能问题(如果您开始嵌套这些上下文绑定的东西).
我不会因此而改变我的编程风格,但要注意它.
如果您不介意少量额外代码,则可以重复使用该using语句.只需将您的包装器代码放在构造函数和Dispose方法中,例如:
public class MyWrapper: IDisposable
{
int _id;
public MyWrapper(int id)
{
_id = id;
Debug.WriteLine("Begin " + _id);
}
public void Dispose()
{
Debug.WriteLine("End " + _id);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
using(new MyWrapper(id))
{
Debug.WriteLine("Middle " + id);
}
Run Code Online (Sandbox Code Playgroud)
我已经使用这种方法来包装需要一起使用的方法,即使出现问题(例如Push和Pop方法DrawingContext) - 为您节省了大量的finally块.