这个功能存在吗?在 C# 中定义我自己的大括号
您将欣赏以下两个语法糖:
lock(obj)
{
//Code
}
same as:
Monitor.Enter(obj)
try
{
//Code
}
finally
{
Monitor.Exit(obj)
}
显然
using(var adapt = new adapter()){
//Code2
}
same as:
var adapt= new adapter()
try{
//Code2
}
finally{
adapt.Dispose()
}
,每种情况下的第一个示例都更具可读性。有没有办法自己定义这种东西,无论是在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
}
}
当然,您必须考虑如何使用 TryEnterReadLocks 和那些类型有回报的东西。但我相信你能想到一些事情。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
不完全是这样,但您可以使用操作委托来获得接近的结果:
并像这样使用它:
请注意,这有一些限制。例如,新大括号内不能有有意义的 return 语句。感谢闭包,您至少仍然可以使用局部变量。
Not exactly, but you can use an action delegate to get something close:
And use it like this:
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.
不幸的是没有。为了支持这一点,c# 编译器需要为最终用户提供更多的可扩展性。这包括能够定义自己的关键字并具有宏支持等...
但是您可以做的是构建至少具有一些类似感觉的方法,例如:
(在用户代码中重新实现 lock 关键字的设计示例)
使用 then 将如下所示:
OR
OR
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)
using then would be like this:
OR
OR
您无法直接定义这样的构造,但有一些方法可以创建类似的简洁模式:
您可以定义实现 IDisposable 的类来封装这种块使用语义。例如,如果您有某个类封装了获取 ReaderWriterLockSlim(在构造时获取,在 Dispose 时释放)读锁,则可以在构造实例的类上创建一个属性,这会产生如下语法
:滥用 IDisposable,但这种模式肯定已经在生产代码中使用过。
您可以使用面向方面的编程(使用 PostSharp 等工具)来包装具有可重用入口/出口的方法主体逻辑。这通常用于注入日志记录或其他您希望应用于代码而不使其混乱的横切关注点。
您可以编写将委托作为参数的函数,然后将委托逻辑包装在一些类似的结构中。例如,对于 ReaderWriterLockSlim,您可以创建如下方法:
这可能非常强大,因为对带有闭包的 lambda 表达式的支持允许任意复杂的逻辑,而无需手动创建包装函数并在字段中传递所需参数。
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:
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:
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.
不,没有办法定义您自己的关键字。它们由语言定义并内置于编译器中以解释为 IL。我们还没有完全达到那个抽象级别!
只要看看当
var
和dynamic
之类的东西被引入时,每个人都会多么兴奋。考虑到这一点,编辑您的帖子以显示您希望
ReaderWriterLockSlim
示例的语法。看看会很有趣。No, there is no way to define your own keywords. These are defined by the language and are built into the compiler to interpret to IL. We haven't quite reached that level of abstraction yet!
Just look at how excited everyone gets when things like
var
anddynamic
are introduced.With that in mind, edit your post to show what you'd like the syntax to be for the
ReaderWriterLockSlim
example. It'd be interesting to see.没有任何本机功能可以满足您的要求。但是,您只需实现
IDisposable
即可利用using
语句。There is no native feature that does what you want. However, you can exploit the
using
statement simply by implementingIDisposable
.就我个人而言,我为此过度滥用1
using
,以至于我有一个DisposeHelper
类:这让我返回一个
IDisposable< /code> 从任意方法很容易:
您也可以内联执行它:
或者,添加一个
onInit
操作:但这只是丑陋的。
1:从技术上讲,我认为这更多的是对
IDisposable
的滥用,而不是使用
。毕竟,我实际上确实想要一个try/finally
- 这就是using
给我的。但事实证明,我必须实现IDisposable
才能获得try/finally
。不管怎样,我都同意。对我来说,语义相当清楚 - 如果您开始某事,我希望您也能完成某事。例如,如果您将“开始任务”消息写入日志文件,我也期望出现“结束任务”日志消息。我只是对“释放资源”的定义比大多数开发人员更具包容性。
Personally, I abuse1
using
so much for this that I have aDisposeHelper
class for this:That lets me return an
IDisposable
from an arbitrary method quite easily:You could also just do it inline:
Or, with the addition of an
onInit
Action:but that's just ugly.
1: Technically, I suppose it's more of an abuse of
IDisposable
than it is ofusing
. After all, I actually do want atry/finally
- which is whatusing
gives me. Turns out, though, that I have to implementIDisposable
to get thetry/finally
.Either way, I'm okay with it. The semantics are fairly clear to me - if you start something, I expect you to finish the something as well. Eg., if you write a "Beginning task" message to the log file, I expect a "Ending task" log message as well. I just have a more inclusive definition of "releasing resources" than most devs.
我知道 Visual Studio 的下一版本将大力推动这种灵活性。
在 .net 岩石上,Anders Hejlsberg 最近表示,下一个 Visual Studio 的主题之一发布(2012?)将是“编译器即服务”,从那时起,其他一些人暗示这将为语言扩展和与 DSL(领域特定语言)更紧密的集成打开很多大门。
现在,您实际上可以使用 DSL 做一些非常巧妙的事情,包括创建您自己的关键字,尽管在我看来这仍然有点尴尬。如果您有兴趣,请查看这篇关于在 Boo 中设计 DSL 的文章。
这可能会让你有点震惊。
I understand there's going to be a big push towards that type of flexibility in the next version of Visual Studio.
On .net rocks, Anders Hejlsberg recently said that one of the main themes of the next Visual Studio release (2012?) will be "compiler as a service" and since then some other folks have hinted that this will open up a lot of doors for language extension and tighter integration with DSLs (Domain-Specific Languages).
Right now you can actually do some pretty neat stuff with DSLs including creating your own keywords, although it's still a little too awkward in my opinion. If you're interested, check out this article on designing DSLs in Boo.
It might blow your mind a little.
魔法类:
用法:
The magical class:
Usage:
我猜您会寻找预处理器指令,但 C# 不会不支持那些。最接近它的可能是Visual Studio snippets,您可以自己设计。
I guess you would be looking for preprocessor directives, but C# doesn't support those. The closest to it might be Visual Studio snippets, which you can design yourself.
正如其他人已经说过的,
IDisposable
可以被滥用来创建As others have already said,
IDisposable
can be abused to create the notion of a scope in your code. It can even support nesting.