首页 > 编程语言 >c#反射和特性配合使用案例说明

c#反射和特性配合使用案例说明

时间:2023-06-29 09:44:29浏览次数:282  
标签:反射 自定义 验证 c# 特性 ValidationAttribute 案例 类型 属性

在C#中,反射(Reflection)是一个强大的特性,它允许我们在运行时动态地获取和操作类型、成员、方法等信息。以下是一个使用反射的案例,配合特性一起使用,来实现属性验证的功能:

假设我们有一个用户类(User),其中包含了一些属性(如姓名、年龄等),我们想要在设置这些属性值的时候进行一些验证。我们可以定义一个自定义特性(Attribute),命名为"ValidationAttribute",用于标记需要进行验证的属性。

 
using System;
using System.Reflection;

// 自定义特性,用于属性验证
[AttributeUsage(AttributeTargets.Property)]
public class ValidationAttribute : Attribute
{
    public void Validate(object value)
    {
        // 在这里进行属性值的验证逻辑
        // 这里仅作为示例,简单判断字符串长度大于等于5
        if (value is string str && str.Length < 5)
        {
            throw new ArgumentException("字符串长度不能少于5个字符!");
        }
    }
}

// 用户类
public class User
{
    // 使用自定义特性进行属性验证
    [Validation]
    public string Name { get; set; }

    [Validation]
    public int Age { get; set; }
}

public class Program
{
    public static void Main()
    {
        // 创建一个用户对象
        var user = new User();

        // 获取用户类的类型
        Type userType = typeof(User);

        // 遍历用户类的所有属性
        foreach (PropertyInfo prop in userType.GetProperties())
        {
            // 判断属性是否被标记为 ValidationAttribute
            if (prop.GetCustomAttribute(typeof(ValidationAttribute)) != null)
            {
                // 获取属性的值
                object value = prop.GetValue(user);

                // 调用属性的验证方法
                var validationAttr = (ValidationAttribute)prop.GetCustomAttribute(typeof(ValidationAttribute));
                validationAttr.Validate(value);
            }
        }

        // 如果没有抛出异常,则表示属性验证通过
        Console.WriteLine("属性验证通过!");
    }
}

在上述示例中,我们定义了一个名为"ValidationAttribute"的自定义特性,它用于标记需要进行验证的属性。在主程序中,我们首先创建了一个用户对象(user),然后使用反射获取用户类的类型(userType)。接下来,我们遍历用户类的所有属性,判断是否被标记为"ValidationAttribute",如果是,就获取属性的值,并调用特性的"Validate"方法进行验证。

注意:这只是一个简单的示例,实际应用中可能需要更加复杂的验证逻辑。同时,这里只展示了属性的验证,实际开发中还可以使用反射实现方法的调用、创建实例等功能。

   

 

var validationAttr = (ValidationAttribute)prop.GetCustomAttribute(typeof(ValidationAttribute));

这段代码的意思是从属性中获取指定类型的自定义特性(ValidationAttribute),并将其转换为ValidationAttribute类型的实例。

具体来说,prop.GetCustomAttribute(typeof(ValidationAttribute)) 这部分代码用于获取与属性关联的自定义特性。GetCustomAttribute 方法可以通过指定特性类型来检索与属性(或其他成员)关联的特性。在这里,我们指定的特性类型是 typeof(ValidationAttribute),即获取与属性关联的 ValidationAttribute 特性。

接下来,我们使用强制类型转换 (ValidationAttribute) 将返回的特性实例转换为 ValidationAttribute 类型的对象。这样我们就可以使用 validationAttr 变量来调用 ValidationAttribute 类型的方法和属性。

总之,这段代码的目的是获取属性上的 ValidationAttribute 特性,并将其转换为 ValidationAttribute 类型的实例,以便后续进行操作,比如调用特性的验证方法。

   

 

为什么要转换成ValidationAttribute

在这段代码中,我们之所以要将获取到的特性转换为 ValidationAttribute 类型,是因为我们知道该属性上的特性就是 ValidationAttribute

通过调用 prop.GetCustomAttribute(typeof(ValidationAttribute)) 方法,我们可以获取属性上的自定义特性。然而,由于 GetCustomAttribute 方法返回的类型是 Attribute,这是所有自定义特性的基类。为了能够使用特定类型的特性的成员(方法、属性等),我们需要将其转换为我们所期望的特性类型。

在这里,我们已经明确知道该属性上的特性是 ValidationAttribute,所以我们可以将其强制转换为 ValidationAttribute 类型,以便后续可以调用 ValidationAttribute 类型中定义的具体方法和属性。

如果我们不进行转换,而是直接使用 Attribute 类型,那么编译器将无法识别和调用 ValidationAttribute 类型中特有的方法,因为 Attribute 类型并没有这些方法。所以,通过转换为特定的特性类型,我们可以更方便地使用和操作特性所提供的功能。

标签:反射,自定义,验证,c#,特性,ValidationAttribute,案例,类型,属性
From: https://www.cnblogs.com/Gdavid/p/17513209.html

相关文章

  • Java流程控制——Scanner对象
    Scanner对象java.until.Scanner是Java5的新特性,可以通过Scanner类来获取用户的输入,实现计算机与人的交互。基础语法:Scanners=newScanner(System.in);通过Scanner类的next()与nextLine()方法获取输入的字符串在读取之前一般需要使用hasNext()和hasNextLine()判断是否还有输......
  • 彻底理解 Node.js 中的回调(Callback)函数
    究竟什么是回调函数(Callback),网上有许许多多的文章,大部分看得人云里雾外,这些文章大概分成两类,第一类堆砌了太多的术语,基本上不明白术语就没法看,另一类反过来,不讲术语,完全是举一些脱离编程的生活化例子来类比,看的人更加晕头转向。作为JS的核心,回调函数和异步执行是紧密相关的,不跨......
  • LLM-Client一个轻量级的LLM集成工具
    大型语言模型(llm)已经彻底改变了我们与文本交互的方式,OpenAI、Google、AI21、HuggingfaceHub、Anthropic和众多开源模型提供了不同的功能和优势。但是每个模型都有其独特的体系结构、api和兼容性需求,集成这些模型是一项耗时且具有挑战性的任务。所以这时候LangChain就解决了这个......
  • 前端Vue自定义简单通用省市区选择器picker地区选择器picker 收获地址界面模版
    前端Vue自定义简单通用省市区选择器picker地区选择器picker收获地址界面模版,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13266效果图如下:代码实现如下:cc-selectDity使用方法<!--省市区选择show:是否显示 @sureSelectArea:确认事件......
  • Taurus .Net Core 微服务开源框架:Admin 插件【4-1】 - 配置管理-Kestrel【含https启用
    前言:继上篇:Taurus.NetCore微服务开源框架:Admin插件【3】-指标统计管理本篇继续介绍下一个内容:1、系统配置节点:App- Config 界面界面图如下:双击节点即可进入修改模式,如: 修改说明: 不勾选持久化,该配置当前生效,下次重次失效,修改后配置值旁边带有【temp】说明文......
  • MFC中使用多线程
    一、在MFC中使用多线程,可以通过CWinThread类来实现。下面是一个简单的示例,演示了如何在MFC应用程序中创建和使用多线程:在你的MFC应用程序中包含头文件"afxmt.h",该头文件包含了多线程相关的类和函数。创建一个派生自CWinThread的自定义线程类。示例代码如下:classMyThrea......
  • 自用gulp打包脚本,压缩html,压缩js,压缩css,压缩图片,功能齐全
    constgulp=require('gulp');constfs=require('fs');consthtmlmin=require('gulp-htmlmin');constuglify=require('gulp-uglify');constuglifyEs=require('uglify-es');constminifyCSS=require(......
  • php通过Curl给接口上传文件。
    在PHP中使用cURL上传文件至接口,你可以通过CURLOPT_POSTFIELDS选项来设置文件的内容。以下是一个示例:functionuploadFile($url,$filePath,$fieldName){$ch=curl_init($url);$postData=array($fieldName=>newCURLFile($filePath));c......
  • 【前端可视化】Canvas 下载图片添加背景色因为缩放导致比例不同问题
    比例不同是因为缩放导致的,缩放导致绘图中心发生改变,我们需要把填充的背景色的范围扩大(根据缩放比例来),同时背景色要绘制在现有画布的后面,防止重叠遮挡。感觉一个小下载,需要注意的事项还是挺多的,记录下,希望能帮助到其他人,里面的一些API请参考MDN文档。下面的参考代码,自己根据......
  • Oracle DataGuard 监控日志同步是否正常
    1.查看备库(或者主库)的状态SETfeedoffSETlines300SETpages999COLUMNdatabase_nameheading"Database|Name"FORMATa12COLUMNdatabase_roleheading"Database|Role"FORMATa30COLUMNprotection_modeheading"Prote......