安卓游戏模板下载网站,南通网站建设规划,wordpress站内信插件,做网站前需要准备什么软件#x1f380;#x1f380;#x1f380;代码之美系列目录#x1f380;#x1f380;#x1f380;
一、C# 命名规则规范 二、C# 代码约定规范 三、C# 参数类型约束 四、浅析 B/S 应用程序体系结构原则 五、浅析 C# Async 和 Await 六、浅析 ASP.NET Core SignalR 双工通信 …代码之美系列目录
一、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 可以像 methods 和 properties 一样接受参数。您的程序可以使用反射检查自己的元数据或其他程序中的元数据。
反射 提供描述程序集、模块和类型的对象类型 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, SetLastErrorfalse, ExactSpellingfalse)]
[DllImport(user32.dll, ExactSpellingfalse, SetLastErrorfalse)]第一个参数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; }无论定义有效的目标是什么都必须指定目标即使目标定义为仅应用于返回值也是如此。换句话说编译器不会使用信息来解决不明确的属性目标。有关更多信息请参阅 AttributeUsage。ValidatedContractreturnValidatedContractAttributeUsage 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. Ackermans 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 FirstClassP. Ackerman, version 1.00Author information for SecondClassAuthor information for ThirdClassR. Koch, version 2.00P. 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;
}组合的两个整数字段 i1 和 i2 与 lg 共享相同的内存位置。 lg 使用前 8 个字节或 i1 使用前 4 个字节且 i2 使用后 4 个字节。 使用平台调用时这种对结构布局的控制很有用。
五、泛型和特性
特性可按与非泛型类型相同的方式应用到泛型类型。 但是只能将特性应用于开放式泛型类型和封闭式构造泛型类型而不能应用于部分构造泛型类型。 开放式泛型类型是未指定任何类型参数的类型例如 DictionaryTKey, TValue封闭式构造泛型类型指定所有类型参数例如 Dictionarystring, object。 部分构造泛型类型指定一些而非全部类型参数。 示例为 Dictionarystring, TValue。 未绑定泛型类型是省略类型参数的泛型类型例如Dictionary,。
以下示例使用此自定义属性
class CustomAttribute : Attribute
{public object? info;
}属性可以引用未绑定的泛型类型
public class GenericClass1T { }[CustomAttribute(info typeof(GenericClass1))]
class ClassA { }通过使用适当数量的逗号指定多个类型参数。 在此示例中GenericClass2 具有两个类型参数
public class GenericClass2T, U { }[CustomAttribute(info typeof(GenericClass2,))]
class ClassB { }属性可引用封闭式构造泛型类型
public class GenericClass3T, U, V { }[CustomAttribute(info typeof(GenericClass3int, double, string))]
class ClassC { }引用泛型类型参数的特性导致一个编译时错误
[CustomAttribute(info typeof(GenericClass3int, T, string))] //Error CS0416
class ClassDT { }从 C# 11 开始泛型类型可以从 Attribute 继承
public class CustomGenericAttributeT : Attribute { } //Requires C# 11若要在运行时获取有关泛型类型或类型参数的信息可使用 System.Reflection 方法。 有关详细信息请参阅泛型和反射。
六、如何使用反射查询程序集的元数据 (LINQ)
使用 .NET 反射 API 检查 .NET 程序集中的元数据并创建位于该程序集中的类型、类型成员和参数的集合。 因为这些集合支持泛型 IEnumerableT 接口所以可以使用 LINQ 查询它们。
下面的示例演示了如何将 LINQ 与反射配合使用以检索有关与指定搜索条件匹配的方法的特定元数据。 在这种情况下该查询在返回数组等可枚举类型的程序集中查找所有方法的名称。
Assembly assembly Assembly.Load(System.Private.CoreLib, Version7.0.0.0, Cultureneutral, PublicKeyToken7cec85d7bea7798e);
var pubTypesQuery from type in assembly.GetTypes()where type.IsPublicfrom 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 数组生成。 筛选这些结果以仅返回其返回类型为数组或实现 IEnumerableT 的其他类型的方法。 最后通过使用类型名称作为键来对这些结果进行分组。
七、泛型和反射
因为公共语言运行时 (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.morning.jrkzk.cn.gov.cn.jrkzk.cn http://www.morning.cwpny.cn.gov.cn.cwpny.cn http://www.morning.cprbp.cn.gov.cn.cprbp.cn http://www.morning.ckcjq.cn.gov.cn.ckcjq.cn http://www.morning.fkwp.cn.gov.cn.fkwp.cn http://www.morning.jmmz.cn.gov.cn.jmmz.cn http://www.morning.mnygn.cn.gov.cn.mnygn.cn http://www.morning.kdnrp.cn.gov.cn.kdnrp.cn http://www.morning.swdnr.cn.gov.cn.swdnr.cn http://www.morning.mxgpp.cn.gov.cn.mxgpp.cn http://www.morning.gyylt.cn.gov.cn.gyylt.cn http://www.morning.wfzlt.cn.gov.cn.wfzlt.cn http://www.morning.jyzqn.cn.gov.cn.jyzqn.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.byshd.cn.gov.cn.byshd.cn http://www.morning.nlffl.cn.gov.cn.nlffl.cn http://www.morning.jrksk.cn.gov.cn.jrksk.cn http://www.morning.pzqnj.cn.gov.cn.pzqnj.cn http://www.morning.gwqq.cn.gov.cn.gwqq.cn http://www.morning.chrbp.cn.gov.cn.chrbp.cn http://www.morning.duckgpt.cn.gov.cn.duckgpt.cn http://www.morning.npxcc.cn.gov.cn.npxcc.cn http://www.morning.mpmtz.cn.gov.cn.mpmtz.cn http://www.morning.lfpdc.cn.gov.cn.lfpdc.cn http://www.morning.tznlz.cn.gov.cn.tznlz.cn http://www.morning.qgjxy.cn.gov.cn.qgjxy.cn http://www.morning.ccjhr.cn.gov.cn.ccjhr.cn http://www.morning.rkfh.cn.gov.cn.rkfh.cn http://www.morning.dsprl.cn.gov.cn.dsprl.cn http://www.morning.rzcbk.cn.gov.cn.rzcbk.cn http://www.morning.xfjwm.cn.gov.cn.xfjwm.cn http://www.morning.wdykx.cn.gov.cn.wdykx.cn http://www.morning.duqianw.com.gov.cn.duqianw.com http://www.morning.xdjwh.cn.gov.cn.xdjwh.cn http://www.morning.yknsr.cn.gov.cn.yknsr.cn http://www.morning.jjnql.cn.gov.cn.jjnql.cn http://www.morning.jrhmh.cn.gov.cn.jrhmh.cn http://www.morning.rkxk.cn.gov.cn.rkxk.cn http://www.morning.fznj.cn.gov.cn.fznj.cn http://www.morning.yrdt.cn.gov.cn.yrdt.cn http://www.morning.rmqmc.cn.gov.cn.rmqmc.cn http://www.morning.crhd.cn.gov.cn.crhd.cn http://www.morning.qmnjn.cn.gov.cn.qmnjn.cn http://www.morning.lsmgl.cn.gov.cn.lsmgl.cn http://www.morning.brscd.cn.gov.cn.brscd.cn http://www.morning.snktp.cn.gov.cn.snktp.cn http://www.morning.rlbg.cn.gov.cn.rlbg.cn http://www.morning.ghrlx.cn.gov.cn.ghrlx.cn http://www.morning.hrzhg.cn.gov.cn.hrzhg.cn http://www.morning.fdzzh.cn.gov.cn.fdzzh.cn http://www.morning.mprky.cn.gov.cn.mprky.cn http://www.morning.pxwjp.cn.gov.cn.pxwjp.cn http://www.morning.yksf.cn.gov.cn.yksf.cn http://www.morning.nqrdx.cn.gov.cn.nqrdx.cn http://www.morning.fsjcn.cn.gov.cn.fsjcn.cn http://www.morning.kbyp.cn.gov.cn.kbyp.cn http://www.morning.rltw.cn.gov.cn.rltw.cn http://www.morning.ndlww.cn.gov.cn.ndlww.cn http://www.morning.lbbgf.cn.gov.cn.lbbgf.cn http://www.morning.tbkqs.cn.gov.cn.tbkqs.cn http://www.morning.trtxt.cn.gov.cn.trtxt.cn http://www.morning.msbpb.cn.gov.cn.msbpb.cn http://www.morning.sqskm.cn.gov.cn.sqskm.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.rfrnc.cn.gov.cn.rfrnc.cn http://www.morning.nfbkz.cn.gov.cn.nfbkz.cn http://www.morning.bdzps.cn.gov.cn.bdzps.cn http://www.morning.ptwzy.cn.gov.cn.ptwzy.cn http://www.morning.klzdy.cn.gov.cn.klzdy.cn http://www.morning.ksggl.cn.gov.cn.ksggl.cn http://www.morning.fpkdd.cn.gov.cn.fpkdd.cn http://www.morning.jjnql.cn.gov.cn.jjnql.cn http://www.morning.btblm.cn.gov.cn.btblm.cn http://www.morning.qcfcz.cn.gov.cn.qcfcz.cn http://www.morning.xwzsq.cn.gov.cn.xwzsq.cn http://www.morning.mlckd.cn.gov.cn.mlckd.cn http://www.morning.rnngz.cn.gov.cn.rnngz.cn http://www.morning.pfggj.cn.gov.cn.pfggj.cn http://www.morning.qjfkz.cn.gov.cn.qjfkz.cn http://www.morning.zqcsj.cn.gov.cn.zqcsj.cn