Are C# Attributes the Same Thing as Python-TypeScript Decorators?
Preface Recently I successfully dragged Frontend Mentor into the C# pit ~~(actually Frontend Mentor started switching from cocos to unity game development)~~ One day, Frontend Mentor saw this code and asked a question: [is this a decorator]? [HttpGet] public Response Get() { return ... } My first reaction was that it isn’t. This thing is called an “attribute” in C# (English name Attribute, hereafter referred to as attributes), and an annotation in Java. Although the syntax is similar to Pyth
目录7 个章节
Preface
Recently I successfully dragged Frontend Mentor into the C# pit (actually Frontend Mentor started switching from cocos to unity game development)
One day, Frontend Mentor saw this code and asked a question: [is this a decorator]?
[HttpGet]
public Response Get() {
return ...
}
My first reaction was that it isn’t. This thing is called an “attribute” in C# (English name Attribute, hereafter referred to as attributes), and an annotation in Java. Although the syntax is similar to that in Python/TypeScript, I had the impression that the implementation should be different.
But those of us trained in science and engineering have to be rigorous and can’t rely on experience and gut feeling alone. For that reason, I looked up some materials and read the book C# in nutshell that expert Yang Xu had recommended before. I not only confirmed the answer to this question, but also learned more about Attributes.
About AOP
“Attributes” and decorators are actually both the decorator pattern in design patterns, and also the idea of AOP.
AOP is Aspect Oriented Programming, that is, aspect-oriented programming.
AOP decomposes a system into different concerns, or what are called aspects (Aspect). It is a programming idea of dynamically weaving code into specified methods and specified locations of a class at runtime
For example, suppose there is a website with shopping, social, gaming, and other features, all open to every user. Now we need to restrict a few of those features so that only premium members can use them. We could add if checks in every module, but that would be too invasive and would create a lot of duplicated code. Switching to the AOP approach means using decorators: just add the restriction where premium membership is required~
Specific Differences
First let’s look at the differences in syntax
Python Decorators
First let’s look at decorators in Python. In Python, functions are first-class citizens, and a decorator is also a function that nests another function inside it
def outer(func):
def inner():
# ... 一些代码
result = func()
return result
return inner
When using it
@outer
def test():
print('test')
The usage syntax is the same as Java annotations, starting with @
This is actually syntactic sugar; the actual effect is equivalent to
outer(test)
The test function is passed as an argument to the decorator. After that, the execution order of this code is as follows:
def outer(func): decorator definition@outer: decorator syntactic sugar, directly executes theouterfunction, passing thetestfunction as an argumentouter: executes the decorator syntax rules, replacing thetestfunction with theinnerfunctioninner: executes theinnerfunction codetest: according to this line of code ininner:result = func(), executes thetestfunction code- return
In a dynamic language like Python, implementing the decorator pattern is indeed easier than in static languages. The decorated content is passed as an argument to the decorator, and the decorator can directly access the decorated content to do some processing.
C# “Attributes”
In C#, an “attribute” is a class that inherits from the Attribute class, and can then contain any property fields you want
Decorated with the AttributeUsage attribute, you can specify which code elements this attribute can decorate
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DemoAttribute : Attribute {
public DemoAttribute(string param1) {
this.param1 = param1;
}
public string param1 { get; set; }
}
The parameters in the constructor are the parameters passed in when using the attribute, for example like this:
[DemoAttribute("class")]
public class DemoClass {
[Demo("method")]
public void Method1() {
}
}
PS: When using an attribute you can omit the trailing "Attribute", so
DemoAttributeandDemoare the same thing
Writing it this way doesn’t produce any effect
Because attributes are merely decoration
When the code runs, the C# compiler first instantiates the DemoAttribute class, then instantiates the DemoClass class, and inside DemoAttribute you cannot obtain the decorated content.
To make the decoration take effect, you need to use it together with reflection~
Reflection refers to a program’s ability to access, inspect, and modify its own state or behavior.
With the following code you can obtain the attributes decorating DemoClass
var info = typeof(DemoClass);
var attributes = info.GetCustomAttributes(true);
With the following code you can obtain the decorated methods, the decoration parameters, and so on
foreach (var methodInfo in typeof(DemoClass).GetMethods()) {
var attribute = (DemoAttribute) Attribute.GetCustomAttribute(methodInfo, typeof(DemoAttribute));
if (attribute != null)
Console.WriteLine("方法 {0} 被装饰,装饰参数 {1}", methodInfo.Name, attribute.param1);
}
After obtaining this information, you then do some further processing with other capabilities provided by reflection, and that implements so-called AOP
Summary
So, although C# attributes and Python/TypeScript decorators differ in syntax and usage, they arrive at the same destination by different paths; the purpose they aim to achieve is indeed similar.
But it wouldn’t be rigorous to say they are the same thing, so they shouldn’t be considered the same thing; rather, they are each language’s way of implementing AOP.
References
- A Comparison of C# Attributes and TypeScript Decorators: https://blog.csdn.net/weixin_43263355/article/details/110137016
- How to Implement Python-like Decorators in C#: https://www.zhihu.com/question/36211661
- AOP Aspect-Oriented Programming: https://bbs.huaweicloud.com/blogs/289045
_EOF_
Are C# Attributes the Same Thing as Python-TypeScript Decorators?
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
C#学习(二)匿名方法和委托的多种使用方式
前言 上次简单介绍了委托的概念和使用,今天继续,并且引入匿名方法的概念,匿名方法在很多语言里面都有,比如Python、js、java8,尤其js,前端小伙伴可能深受js回调地狱之苦,这里面匿名方法功不可没。 js的匿名方法就像这样: 这还没用lambda,因为我想下篇再介绍lambda。 document.querySelector('.btn').onclick = function () {
2021-12-18 · C# · 约 1 分钟
System.Text.Json使用中的几个常见问题
前言 以前.NetCore是不内置JSON库的,所以大家都用Newtonsoft的JSON库,而且也确实挺好用的,不过既然官方出了标准库,那更方便更值得我们多用用,至少不用每次都nuget安装Newtonsoft.Json库了。 不过日常开发使用中会有一些问题,本文记录一下解决方法,欢迎交流~ ~~(文章末尾包含小彩蛋)~~ 字符编码问题 默认的 System.Text.Json 序列化的时候会把
2022-05-27 · C# · 约 1 分钟
纯 C#实现+AOT 打造的智能PDF目录提取工具 PdfTocExtractor
用C#写个PDF目录提取工具?挺有意思,还整什么语义识别,效果真有那么好吗?AOT编译挺香,但别搞得太复杂就行。
2025-08-20 · C# · 约 1 分钟
开发现代化的.NetCore控制台程序:(1)项目介绍以及依赖注入/配置/日志等使用细节
开发.NET Core控制台工具,依赖注入和日志整合得比Go优雅多了。哼,配置文件丝滑,但AOT?反射问题,放弃。
2023-11-10 · C# · 约 1 分钟
讨论
共 0 条加载评论中…