c#中的自定义复合语句
Custom Compound statements in c#
我想编写自己的自定义复合语句,它们具有与 using
和 lock
机制类似的机制,它们在编译前在语句块的开头和结尾注入代码。
我曾尝试搜索可能问过类似问题的问题,但我无法正确弄清楚这种 "code scoping" 的名称,除了文档中说这些是复合语句之外。
我知道 "lock" 和 "using" 是关键字。我不想拥有自己的关键字,因为我知道这是不可能的。
我不确定这在 c# 中是否可行,例如:
而不是做:
StartContext(8);
//make method calls
EndContext();
这可以减少到:
DoSomethingInContext(8) {
//make method calls
}
当然,这不一定只是一个单行调用。封装代码的开始和结束可以是自定义复合语句插入的多行代码。
如果您不介意少量的额外代码,您可以 re-use 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);
}
}
用法:
using(new MyWrapper(id))
{
Debug.WriteLine("Middle " + id);
}
演示 DotNetFiddle
我已经用这个方法包装了需要一起使用的方法,即使出现问题(例如 DrawingContext
的 Push
和 Pop
方法)- 保存你很多finally
块。
您可以稍微重写您的代码:
DoSomethingInContext(8, () => {
// make method calls
});
您方法的签名如下所示:
public void DoSomethingInContext(int contextId, Action contextBoundAction)
{
// start/open/enter context
try
{
contextBoundAction();
}
finally
{
// stop/close/exit context
}
}
需要注意的一件事是,由于这里有一个使用 IDisposable
的替代答案,因此 delegate-based 语法可以在 [=25= 的各种(旧)版本中进行智能感知] 和 ReSharper 变得有点不稳定。有时它会尝试帮助您填写 DoSomethingInContext
的参数,而当您确实希望它帮助您填写委托内部方法调用中的参数时。这对于其他 IDE 也是如此,例如较旧的 Xamarin Studios,它们在嵌套委托方面存在严重的性能问题(如果您开始嵌套这些 context-bound 东西)。
我不会因此而改变我的编程风格,但请注意这一点。
我想编写自己的自定义复合语句,它们具有与 using
和 lock
机制类似的机制,它们在编译前在语句块的开头和结尾注入代码。
我曾尝试搜索可能问过类似问题的问题,但我无法正确弄清楚这种 "code scoping" 的名称,除了文档中说这些是复合语句之外。
我知道 "lock" 和 "using" 是关键字。我不想拥有自己的关键字,因为我知道这是不可能的。
我不确定这在 c# 中是否可行,例如:
而不是做:
StartContext(8);
//make method calls
EndContext();
这可以减少到:
DoSomethingInContext(8) {
//make method calls
}
当然,这不一定只是一个单行调用。封装代码的开始和结束可以是自定义复合语句插入的多行代码。
如果您不介意少量的额外代码,您可以 re-use 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);
}
}
用法:
using(new MyWrapper(id))
{
Debug.WriteLine("Middle " + id);
}
演示 DotNetFiddle
我已经用这个方法包装了需要一起使用的方法,即使出现问题(例如 DrawingContext
的 Push
和 Pop
方法)- 保存你很多finally
块。
您可以稍微重写您的代码:
DoSomethingInContext(8, () => {
// make method calls
});
您方法的签名如下所示:
public void DoSomethingInContext(int contextId, Action contextBoundAction)
{
// start/open/enter context
try
{
contextBoundAction();
}
finally
{
// stop/close/exit context
}
}
需要注意的一件事是,由于这里有一个使用 IDisposable
的替代答案,因此 delegate-based 语法可以在 [=25= 的各种(旧)版本中进行智能感知] 和 ReSharper 变得有点不稳定。有时它会尝试帮助您填写 DoSomethingInContext
的参数,而当您确实希望它帮助您填写委托内部方法调用中的参数时。这对于其他 IDE 也是如此,例如较旧的 Xamarin Studios,它们在嵌套委托方面存在严重的性能问题(如果您开始嵌套这些 context-bound 东西)。
我不会因此而改变我的编程风格,但请注意这一点。