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# 也拥有 gofmt 般的体验:用 CSharpier + Roslyn 实现 csfmt
C# 代码长到像答辩?用 CSharpier 自动折行,再用 Roslyn 修正 K&R 花括号,Taskfile 一键收尾。再补上 format-check,省得 CI 反复制造 Git diff。两步流水线并非原生 gofmt,顺序和版本仍得老实锁住。
2026-10-22 · C# · 约 1 分钟
Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。
又一个把Django/Rails那套“约定优于配置”搬进.NET生态的尝试,看着有点意思。预置了认证、队列、定时任务这些破事,省得自己天天重复造轮子。但767个star连个正式release都没有,就敢打着“生产级”旗号?呵,C#全栈爱好者们可以先玩玩,但别指望它能替代ASP.NET Core的体量。
2026-04-29 · C# · 约 1 分钟
C#爬虫:CatSpider#-开发笔记
前言 (PS:我这里用了#号代替了Sharp这个单词) CatSpider是毕设里的数据采集模块,本来爬虫类的应用肯定使用python来开发嘛,不过用request_html做解析的时候,python的动态类型真的把我恶心到了,而且感觉这个库也不是很成熟,html5lib也不好用,也没心思去深入了,之前看到有大佬用.net core平台做爬虫,于是我也来试试,没想到效果贼好,特别是配合LinqPa
2022-05-27 · C# · 约 1 分钟
System.Text.Json使用中的几个常见问题
前言 以前.NetCore是不内置JSON库的,所以大家都用Newtonsoft的JSON库,而且也确实挺好用的,不过既然官方出了标准库,那更方便更值得我们多用用,至少不用每次都nuget安装Newtonsoft.Json库了。 不过日常开发使用中会有一些问题,本文记录一下解决方法,欢迎交流~ ~~(文章末尾包含小彩蛋)~~ 字符编码问题 默认的 System.Text.Json 序列化的时候会把
2022-05-27 · C# · 约 1 分钟
讨论
共 0 条加载评论中…