C#高级篇 反射和属性详解【代码之美系列】

news2025/1/5 22:53:36

🎀🎀🎀代码之美系列目录🎀🎀🎀

一、C# 命名规则规范
二、C# 代码约定规范
三、C# 参数类型约束
四、浅析 B/S 应用程序体系结构原则
五、浅析 C# Async 和 Await
六、浅析 ASP.NET Core SignalR 双工通信
七、浅析 ASP.NET Core 和 MongoDB 创建 Web API
八、浅析 ASP.NET Web UI 框架 Razor Pages/MVC/Web API/Blazor
九、如何使用 MiniProfiler WebAPI 分析工具
十、浅析 .NET Core 中各种 Filter
十一、C#.Net筑基-类型系统
十二、C#.Net 筑基-运算符
十三、C#.Net筑基-解密委托与事件
十四、C#.Net筑基-集合知识大全
十五、C#.Net筑基 - 常见类型
十六、C#.NET体系图文概述—2024最全总结
十七、C# 强大无匹的模式匹配,让代码更加优雅
十八、C# 中的记录类型简介
十九、C# 异步编程模型【代码之美系列】
二十、C#高级篇 反射和属性详解【代码之美系列】


在这里插入图片描述


文章目录

  • 🎀🎀🎀代码之美系列目录🎀🎀🎀
  • 一、属性
    • 1.1 使用属性
    • 1.2 属性参数
    • 1.3 属性目标
    • 1.4 属性的常见用途
    • 1.5 反射概述
  • 二、创建自定义特性
  • 三、使用反射访问特性
  • 四、如何使用特性 (C#) 创建 C/C++ 联合
  • 五、泛型和特性
  • 六、如何使用反射查询程序集的元数据 (LINQ)
  • 七、泛型和反射


一、属性

特性 提供了一种将 元数据声明性 信息与代码(程序集、类型、方法、属性等)相关联的强大方法。将属性与程序实体关联后,可以在 运行时 使用称为反射的技术查询该属性。

属性具有以下属性:

  • 属性将元数据添加到程序中。元数据是有关程序中定义的类型的信息。所有 .NET 程序集都包含一组指定的元数据,用于描述程序集中定义的类型和类型成员。您可以添加自定义属性以指定所需的任何其他信息。
  • 您可以将一个或多个属性应用于整个程序集、模块或较小的程序元素,例如类和属性。
  • Attributes 可以像 methodsproperties 一样接受参数。
  • 您的程序可以使用反射检查自己的元数据或其他程序中的元数据。

反射 提供描述程序集、模块和类型的对象(类型 Type)。您可以使用反射动态创建类型的实例,将类型绑定到现有对象,或者从现有对象获取类型并调用其方法或访问其字段和属性。如果您在代码中使用属性,则反射使您能够访问它们。

下面是一个使用 GetType() 方法(由基类中的所有类型继承)获取变量类型的反射的简单示例:Object

确保在 .cs 文件的顶部添加 and 。using System;using System.Reflection;

// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

输出为: .System.Int32

下面的示例使用反射来获取加载的程序集的全名。

// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

C# 关键字 和 在中间语言 (IL) 中没有意义,也不用于反射 API。IL 中的相应术语是 Family 和 Assembly。若要使用反射标识方法,请使用 IsAssembly 属性。若要标识方法,请使用 IsFamilyOrAssembly。protectedinternalinternalprotected internal

1.1 使用属性

属性几乎可以放置在任何声明上,尽管特定属性可能会限制它有效的声明类型。在 C# 中,可以通过将用方括号 () 括起来的特性名称放在应用该特性的实体的声明上方来指定特性。[]

在此示例中,SerializableAttribute 属性用于将特定特征应用于类:

[Serializable]
public class SampleClass
{
    // Objects of this type can be serialized.
}

具有 DllImportAttribute 属性的方法的声明类似于以下示例:

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();

可以在声明上放置多个属性,如下例所示:

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

可以为给定实体多次指定某些属性。此类 multiuse 属性的一个示例是 ConditionalAttribute

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
    // ...
}

按照约定,所有 属性名称 都以单词 “Attribute” 结尾,以便将它们与 .NET 库中的其他项区分开来。但是,在代码中使用属性时,无需指定属性后缀。例如,等效于 ,但 是 .NET 类库中属性的实际名称。[DllImport][DllImportAttribute]DllImportAttribute

1.2 属性参数

许多属性都有参数,这些参数可以是 positional、unnamed 或 named。任何位置参数都必须按特定顺序指定,并且不能省略。命名参数是可选的,可以按任意顺序指定。首先指定位置参数。例如,这三个属性是等效的:

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

第一个参数(DLL 名称)是位置参数,始终排在最前面;其他的都被命名了。在这种情况下,两个命名参数都默认为 false,因此可以省略它们。位置参数对应于属性构造函数的参数。命名参数或可选参数对应于属性的属性或字段。有关默认参数值的信息,请参阅单个属性的文档。

有关允许的参数类型的更多信息,请参见 C# 语言规范的 Attributes 部分

1.3 属性目标

属性的目标是属性应用到的实体。例如,特性可能应用于类、特定方法或整个程序集。默认情况下,属性适用于其后面的元素。但是,您也可以显式标识,例如,属性是应用于方法、参数还是返回值。

要显式标识属性目标,请使用以下语法:

[target : attribute-list]

下表显示了可能的值列表。target

在这里插入图片描述
您可以指定目标值,以将属性应用于为自动实现的属性创建的支持字段。field

下面的示例演示如何将属性应用于程序集和模块。有关更多信息,请参见 通用属性 (C#)。

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

下面的示例演示如何在 C# 中将属性应用于方法、方法参数和方法返回值。

// default: applies to method
[ValidatedContract]
int Method1() { return 0; }

// applies to method
[method: ValidatedContract]
int Method2() { return 0; }

// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }

// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

无论定义有效的目标是什么,都必须指定目标,即使目标定义为仅应用于返回值也是如此。换句话说,编译器不会使用信息来解决不明确的属性目标。有关更多信息,请参阅 AttributeUsageValidatedContractreturnValidatedContractAttributeUsage

1.4 属性的常见用途

以下列表包括代码中 attribute 的一些常见用法:

  • 在 Web 服务中使用该属性标记方法,以指示该方法应可通过 SOAP 协议调用。有关更多信息,请参阅 WebMethodAttribute。WebMethod
  • 描述在与本机代码互操作时如何封送方法参数。有关详细信息,请参阅 MarshalAsAttribute
  • 描述类、方法和接口的 COM 属性。
  • 使用 DllImportAttribute 类调用非托管代码。
  • 根据标题、版本、描述或商标来描述程序集。
  • 描述要序列化的类的哪些成员以实现持久性。
  • 描述如何在类成员和 XML 节点之间进行映射以进行 XML 序列化。
  • 描述方法的安全要求。
  • 指定用于强制实施安全性的特征。
  • 通过即时 (JIT) 编译器控制优化,使代码易于调试。
  • 获取有关方法的调用方的信息。

1.5 反射概述

反射 在以下情况下非常有用:

  • 当您必须访问程序元数据中的属性时。有关更多信息,请参阅检索存储在属性中的信息。
  • 用于检查和实例化程序集中的类型。
  • 用于在运行时构建新类型。使用 System.Reflection.Emit 中的类。
  • 为了执行后期绑定,访问在运行时创建的类型的方法。请参阅动态加载和使用类型一文。

二、创建自定义特性

可通过定义特性类创建自己的自定义特性,特性类是直接或间接派生自 Attribute 的类,可快速轻松地识别元数据中的特性定义。 假设希望使用编写类型的程序员的姓名来标记该类型。 可能需要定义一个自定义 Author 特性类:

[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct)
]
public class AuthorAttribute : System.Attribute
{
    private string Name;
    public double Version;

    public AuthorAttribute(string name)
    {
        Name = name;
        Version = 1.0;
    }
}

类名 AuthorAttribute 是该特性的名称,即 Author 加上 Attribute 后缀。 由于该类派生自 System.Attribute,因此它是一个自定义特性类。 构造函数的参数是自定义特性的位置参数。 在此示例中,name 是位置参数。 所有公共读写字段或属性都是命名参数。 在本例中,version 是唯一的命名参数。 请注意,使用 AttributeUsage 特性可使 Author 特性仅对类和 struct 声明有效。

可按如下方式使用这一新特性:

[Author("P. Ackerman", Version = 1.1)]
class SampleClass
{
    // P. Ackerman's code goes here...
}

AttributeUsage 有一个命名参数 AllowMultiple,通过此命名参数可一次或多次使用自定义特性。 下面的代码示例创建了一个多用特性。

[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{
    string Name;
    public double Version;

    public AuthorAttribute(string name)
    {
        Name = name;

        // Default value.
        Version = 1.0;
    }

    public string GetName() => Name;
}

在下面的代码示例中,某个类应用了同一类型的多个特性。

[Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
public class ThirdClass
{
    // ...
}

三、使用反射访问特性

你可以定义自定义特性并将其放入源代码中这一事实,在没有检索该信息并对其进行操作的方法的情况下将没有任何价值。 通过使用反射,可以检索通过自定义特性定义的信息。 主要方法是 GetCustomAttributes,它返回对象数组,这些对象在运行时等效于源代码特性。 此方法有许多重载版本。 有关详细信息,请参阅 Attribute

特性规范,例如:

[Author("P. Ackerman", Version = 1.1)]
class SampleClass { }

在概念上等效于以下代码:

var anonymousAuthorObject = new Author("P. Ackerman")
{
    Version = 1.1
};

但是,在为特性查询 SampleClass 之前,代码将不会执行。 对 SampleClass 调用 GetCustomAttributes 会导致构造并初始化一个 Author 对象。 如果该类具有其他特性,则将以类似方式构造其他特性对象。 然后 GetCustomAttributes 会以数组形式返回 Author 对象和任何其他特性对象。 之后你便可以循环访问此数组,根据每个数组元素的类型确定所应用的特性,并从特性对象中提取信息。

下面是完整的示例。 定义自定义特性、将其应用于多个实体,并通过反射对其进行检索。

// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{
    string Name;
    public double Version;

    public AuthorAttribute(string name)
    {
        Name = name;

        // Default value.
        Version = 1.0;
    }

    public string GetName() => Name;
}

// Class with the Author attribute.
[Author("P. Ackerman")]
public class FirstClass
{
    // ...
}

// Class without the Author attribute.
public class SecondClass
{
    // ...
}

// Class with multiple Author attributes.
[Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
public class ThirdClass
{
    // ...
}

class TestAuthorAttribute
{
    public static void Test()
    {
        PrintAuthorInfo(typeof(FirstClass));
        PrintAuthorInfo(typeof(SecondClass));
        PrintAuthorInfo(typeof(ThirdClass));
    }

    private static void PrintAuthorInfo(System.Type t)
    {
        System.Console.WriteLine($"Author information for {t}");

        // Using reflection.
        System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // Reflection.

        // Displaying output.
        foreach (System.Attribute attr in attrs)
        {
            if (attr is AuthorAttribute a)
            {
                System.Console.WriteLine($"   {a.GetName()}, version {a.Version:f}");
            }
        }
    }
}
/* Output:
    Author information for FirstClass
       P. Ackerman, version 1.00
    Author information for SecondClass
    Author information for ThirdClass
       R. Koch, version 2.00
       P. Ackerman, version 1.00
*/

四、如何使用特性 (C#) 创建 C/C++ 联合

通过使用特性,可自定义结构在内存中的布局方式。 例如,可使用 StructLayout(LayoutKind.Explicit) 和 FieldOffset 特性在 C/C++ 中创建所谓的联合。

在此代码段中,TestUnion 的所有字段均从内存中的同一位置开始。

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestUnion
{
    [System.Runtime.InteropServices.FieldOffset(0)]
    public int i;

    [System.Runtime.InteropServices.FieldOffset(0)]
    public double d;

    [System.Runtime.InteropServices.FieldOffset(0)]
    public char c;

    [System.Runtime.InteropServices.FieldOffset(0)]
    public byte b;
}

以下代码是另一个示例,其中的字段从不同的显式设置位置开始。

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
struct TestExplicit
{
    [System.Runtime.InteropServices.FieldOffset(0)]
    public long lg;

    [System.Runtime.InteropServices.FieldOffset(0)]
    public int i1;

    [System.Runtime.InteropServices.FieldOffset(4)]
    public int i2;

    [System.Runtime.InteropServices.FieldOffset(8)]
    public double d;

    [System.Runtime.InteropServices.FieldOffset(12)]
    public char c;

    [System.Runtime.InteropServices.FieldOffset(14)]
    public byte b;
}

组合的两个整数字段 i1i2lg 共享相同的内存位置。 lg 使用前 8 个字节,或 i1 使用前 4 个字节且 i2 使用后 4 个字节。 使用平台调用时,这种对结构布局的控制很有用。

五、泛型和特性

特性可按与非泛型类型相同的方式应用到泛型类型。 但是,只能将特性应用于开放式泛型类型和封闭式构造泛型类型,而不能应用于部分构造泛型类型。 开放式泛型类型是未指定任何类型参数的类型,例如 Dictionary<TKey, TValue>;封闭式构造泛型类型指定所有类型参数,例如 Dictionary<string, object>。 部分构造泛型类型指定一些(而非全部)类型参数。 示例为 Dictionary<string, TValue>。 未绑定泛型类型是省略类型参数的泛型类型,例如Dictionary<,>。

以下示例使用此自定义属性:

class CustomAttribute : Attribute
{
    public object? info;
}

属性可以引用未绑定的泛型类型:

public class GenericClass1<T> { }

[CustomAttribute(info = typeof(GenericClass1<>))]
class ClassA { }

通过使用适当数量的逗号指定多个类型参数。 在此示例中,GenericClass2 具有两个类型参数:

public class GenericClass2<T, U> { }

[CustomAttribute(info = typeof(GenericClass2<,>))]
class ClassB { }

属性可引用封闭式构造泛型类型:

public class GenericClass3<T, U, V> { }

[CustomAttribute(info = typeof(GenericClass3<int, double, string>))]
class ClassC { }

引用泛型类型参数的特性导致一个编译时错误:

[CustomAttribute(info = typeof(GenericClass3<int, T, string>))]  //Error CS0416
class ClassD<T> { }

从 C# 11 开始,泛型类型可以从 Attribute 继承:

public class CustomGenericAttribute<T> : Attribute { }  //Requires C# 11

若要在运行时获取有关泛型类型或类型参数的信息,可使用 System.Reflection 方法。 有关详细信息,请参阅泛型和反射。

六、如何使用反射查询程序集的元数据 (LINQ)

使用 .NET 反射 API 检查 .NET 程序集中的元数据,并创建位于该程序集中的类型、类型成员和参数的集合。 因为这些集合支持泛型 IEnumerable<T> 接口,所以可以使用 LINQ 查询它们。

下面的示例演示了如何将 LINQ 与反射配合使用以检索有关与指定搜索条件匹配的方法的特定元数据。 在这种情况下,该查询在返回数组等可枚举类型的程序集中查找所有方法的名称。

Assembly assembly = Assembly.Load("System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");
var pubTypesQuery = from type in assembly.GetTypes()
                    where type.IsPublic
                    from method in type.GetMethods()
                    where method.ReturnType.IsArray == true
                        || (method.ReturnType.GetInterface(
                            typeof(System.Collections.Generic.IEnumerable<>).FullName!) != null
                        && method.ReturnType.FullName != "System.String")
                    group method.ToString() by type.ToString();

foreach (var groupOfMethods in pubTypesQuery)
{
    Console.WriteLine("Type: {0}", groupOfMethods.Key);
    foreach (var method in groupOfMethods)
    {
        Console.WriteLine("  {0}", method);
    }
}

该示例使用 Assembly.GetTypes 方法返回指定程序集中的类型的数组。 将应用 where 筛选器,以便仅返回公共类型。 对于每个公共类型,子查询使用从 Type.GetMethods 调用返回的 MethodInfo 数组生成。 筛选这些结果,以仅返回其返回类型为数组或实现 IEnumerable<T> 的其他类型的方法。 最后,通过使用类型名称作为键来对这些结果进行分组。

七、泛型和反射

因为公共语言运行时 (CLR) 能够在运行时访问泛型类型信息,所以可以使用反射获取关于泛型类型的信息,方法与用于非泛型类型的方法相同。 有关详细信息,请参阅运行时中的泛型。

System.Reflection.Emit 命名空间还包含支持泛型的新成员。 请参阅如何:使用反射发出定义泛型类型。

有关泛型反射中使用的术语的固定条件列表,请参阅 IsGenericType 属性注解:

  • IsGenericType:如果类型是泛型,则返回 true
  • GetGenericArguments:返回 Type 对象的数组,这些对象表示为构造类型提供的类型实参或泛型类型定义的类型形参。
  • GetGenericTypeDefinition:返回当前构造类型的基础泛型类型定义。
  • GetGenericParameterConstraints:返回表示当前泛型类型参数约束的 Type 对象的数组。
  • ContainsGenericParameters:如果类型或任何其封闭类型或方法包含未提供特定类型的类型参数,则返回 true。
  • GenericParameterAttributes:获取描述当前泛型类型参数的特殊约束的 * GenericParameterAttributes 标志组合。
  • GenericParameterPosition:对于表示类型参数的 Type 对象,获取类型参数在声明其类型参数的泛型类型定义或泛型方法定义的类型参数列表中的位置。
  • IsGenericParameter:获取一个值,该值指示当前 Type 是否表示泛型类型或方法定义中的类型参数。
  • IsGenericTypeDefinition:获取一个值,该值指示当前 Type 是否表示可以用来构造其他泛型类型的泛型类型定义。 如果该类型表示泛型类型的定义,则返回 true
  • DeclaringMethod:返回定义当前泛型类型参数的泛型方法,如果类型参数未由泛型方法定义,则返回 null
  • MakeGenericType:替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 Type 对象。

此外,MethodInfo 类的成员还为泛型方法启用运行时信息。 有关用于反射泛型方法的术语的固定条件列表,请参阅 IsGenericMethod 属性注解:

  • IsGenericMethod:如果方法是泛型,则返回 true。
  • GetGenericArguments:返回类型对象的数组,这些对象表示构造泛型方法的类型实参或泛型方法定义的类型形参。
  • GetGenericMethodDefinition:返回当前构造方法的基础泛型方法定义。
  • ContainsGenericParameters:如果方法或任何其封闭类型包含未提供特定类型的任何类型参数,则返回 true。
  • IsGenericMethodDefinition:如果当前 MethodInfo 表示泛型方法的定义,则返回 true
  • MakeGenericMethod:用类型数组的元素替代当前泛型方法定义的类型参数,并返回表示结果构造方法的 MethodInfo 对象。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2270600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL5.7.26-Linux-安装(2024.12)

文章目录 1.下载压缩包1.访问MySQL版本归档2.找到5.7.26并下载3.百度网盘 2.Linux安装1.卸载原来的MySQL8.0.26&#xff08;如果没有则无需在意&#xff09;1.查看所有mysql的包2.批量卸载3.删除残留文件**配置文件**&#xff08;默认路径&#xff09;&#xff1a; 4.**验证卸载…

数据分析思维(六):分析方法——相关分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

前 5 名 IPhone 解锁工具/软件

设备已禁用并且您无法访问它&#xff1f;如果您无法通过密码解锁&#xff0c;尝试 iPhone 解锁软件可能是最好的解决方案。 虽然市场上有很多免费或付费的 iPhone 解锁工具&#xff0c;但您可能不知道它们之间的区别以及如何选择最适合您的工具。 本文将介绍 5 款iPhone 解锁…

【LeetCode Hot100 回溯】组合、排列、子集、分割、N皇后、单词搜索、括号生成、电话号码的字母组合

回溯 组合问题组合总和全排列子集分割回文串N皇后电话号码的字母组合单词搜索括号生成 组合问题 给定两个整数 n 和 k&#xff0c;返回 1 … n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 树形结构&#xff1…

Docker--Docker Container(容器) 之 操作实例

容器的基本操作 容器的操作步骤其实很简单&#xff0c;根据拉取的镜像&#xff0c;进行启动&#xff0c;后可以查看容器&#xff0c;不用时停止容器&#xff0c;删除容器。 下面简单演示操作步骤 1.创建并运行容器 例如&#xff0c;创建一个名为"my-nginx"的交互…

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…

Python爬虫入门实例:Python7个爬虫小案例(附源码)

引言 随着互联网的快速发展&#xff0c;数据成为了新时代的石油。Python作为一种高效、易学的编程语言&#xff0c;在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例&#xff0c;帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&#xff0c;又…

LeetCode - 初级算法 数组(只出现一次的数字)

只出现一次的数字 这篇文章讨论如何找到一个数组中只出现一次的数字,确保算法的时间复杂度为线性,且只使用常量额外空间。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个非空整数数组 nums,除了某个元素只出现一次以外,其余每个元素均出现两…

【视频笔记】基于PyTorch从零构建多模态(视觉)大模型 by Umar Jamil【持续更新】

视频链接: 基于PyTorch从零构建多模态(视觉)大模型 by Umar Jamil 从头编写一个视觉语言模型:PloyGamma,是谷歌的一个模型 1:原始图像 2:视觉编码器(本文是viT),通过对比学习进行训练。这个对比学习最开始是CLIP,后来被谷歌改成了SigLIP 3:线性投影层 4:如何将图…

Doris 2.1 Deleting Data 学习笔记

1 Deleting Data with DELETE Command 1.1 Delete by Specifying a Filter Predicate DELETE FROM table_name [table_alias] [PARTITION partition_name | PARTITIONS (partition_name [

基于51单片机(STC12C5A60S2)和8X8彩色点阵屏(WS2812B驱动)的小游戏《贪吃蛇》(普中开发板矩阵按键控制)

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、定时器02、矩阵按键3、8X8彩色点阵屏 四、主函数总结 系列文章目录 前言 《贪吃蛇》&#xff0c;一款经典的、怀旧的小游戏&#xff0c;单片机入门必写程序。 以《贪吃蛇》为载体&#xff0c;熟悉各种屏幕的使…

爆肝1个月:DDR4 的信号完整性(万字长文SI)

前言&#xff1a; 大学里面&#xff0c;总有很多课程&#xff0c;很浪费时间&#xff0c;学了没点用处&#xff0c;问过老师&#xff0c;为什么信号完整性&#xff0c;示波器使用等课程不开呢&#xff0c;这种是对工作真实有帮助的&#xff1f; 老师&#xff1a;因为老师…

使用Xjar给SpringBoot项目jar包加密

1. 新建一个SpringBoot项目 2. 在pom文件添加依赖&#xff0c;github地址&#xff1a;https://github.com/core-lib/xjar <dependencies><!-- 添加 XJar 依赖 --><dependency><groupId>com.github.core-lib</groupId><artifactId>xjar&l…

UNI-APP_i18n国际化引入

官方文档&#xff1a;https://uniapp.dcloud.net.cn/tutorial/i18n.html vue2中使用 1. 新建文件 locale/index.js import en from ./en.json import zhHans from ./zh-Hans.json import zhHant from ./zh-Hant.json const messages {en,zh-Hans: zhHans,zh-Hant: zhHant }…

AI大模型系列之七:Transformer架构讲解

目录 Transformer网络是什么&#xff1f; 输入模块结构&#xff1a; 编码器模块结构&#xff1a; 解码器模块: 输出模块结构&#xff1a; Transformer 具体是如何工作的&#xff1f; Transformer核心思想是什么&#xff1f; Transformer的代码架构 自注意力机制是什么…

【Linux】:多线程(读写锁 自旋锁)

✨ 倘若南方知我意&#xff0c;莫将晚霞落黄昏 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#…

SELECT的使用

目录 1、SQL的查询命令 1.1 SELECT语句 1.2 投影查询 1.3 选择查询 1.4 聚合函数查询 1.5 简单分组查询(GROUP BY) 1.6 内连接查询 1.7 外连接查询 1.8 子查询 1. 无关子查询 2. 相关子查询 带exists的相关子查询&#xff1a; 1.9 集合查询 1. UNION(并) 2. INT…

Vue项目结构推荐(复杂国际化项目与一般项目结构)

Vue项目结构推荐 一、一般项目结构二、复杂国际化项目结构总结/建议 下面结构是基于Vue和TypeScript开发的项目结构下src包下的结构&#xff0c;若只用到vue与js。则去掉typescript部分的包即可。 一、一般项目结构 assets&#xff1a;存放静态资源&#xff0c;如图片、字体、样…

BOC调制信号matlab性能仿真分析,对比功率谱,自相关性以及抗干扰性

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…

电影院售票 - 策略模式(Strategy Pattern)

策略模式&#xff08;Strategy Pattern&#xff09; 策略模式&#xff08;Strategy Pattern&#xff09;策略模式概述策略模式结构图策略模式主要包含的角色 talk is cheap&#xff0c; show you my code总结 策略模式&#xff08;Strategy Pattern&#xff09; 策略模式&…