使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型...

本文详细介绍了如何使用C#反射中的MakeGenericType函数来指定泛型方法和泛型类的具体类型。通过实例展示了如何调用泛型方法并为其指定类型参数,以及如何为泛型类指定类型并调用其静态方法。
部署运行你感兴趣的模型镜像

C#反射中的MakeGenericType函数可以用来指定泛型方法和泛型类的具体类型,方法如下面代码所示这里就不多讲了,详情看下面代码一切就清楚了:

using System;
using System.Reflection;

namespace RFTest
{
    //类ReflectionTest中定义了一个泛型函数DisplayType和泛型类MyGenericClass
    class ReflectionTest
    {
        //泛型类MyGenericClass有个静态函数DisplayNestedType
        public class MyGenericClass<T>
        {
            public static void DisplayNestedType()
            {
                Console.WriteLine(typeof(T).ToString());
            }
        }

        public void DisplayType<T>()
        {
            Console.WriteLine(typeof(T).ToString());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ReflectionTest rt = new ReflectionTest();

            MethodInfo mi = rt.GetType().GetMethod("DisplayType");//先获取到DisplayType<T>的MethodInfo反射对象
            mi.MakeGenericMethod(new Type[] { typeof(string) }).Invoke(rt, null);//然后使用MethodInfo反射对象调用ReflectionTest类的DisplayType<T>方法,这时要使用MethodInfo的MakeGenericMethod函数指定函数DisplayType<T>的泛型类型T

            Type myGenericClassType = rt.GetType().GetNestedType("MyGenericClass`1");//这里获取MyGenericClass<T>的Type对象,注意GetNestedType方法的参数要用MyGenericClass`1这种格式才能获得MyGenericClass<T>的Type对象
            myGenericClassType.MakeGenericType(new Type[] { typeof(float) }).GetMethod("DisplayNestedType", BindingFlags.Static | BindingFlags.Public).Invoke(null, null);
            //然后用Type对象的MakeGenericType函数为泛型类MyGenericClass<T>指定泛型T的类型,比如上面我们就用MakeGenericType函数将MyGenericClass<T>指定为了MyGenericClass<float>,然后继续用反射调用MyGenericClass<T>的DisplayNestedType静态方法

            Console.ReadLine();
        }
    }
}

 

转载于:https://www.cnblogs.com/OpenCoder/p/5957668.html

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在讨论C#函数中的使用方法作用。根据用户的问题,我们需要聚焦于方法(Generic Methods)的使用。 引用[2]引用[3]提供了关于方法的示例,我们可以以此为基础展开。 方法允许我们在定义方法使用类型参数,这样方法可以接受不同类型的参数,同时保持类型安全。 主要作用: 1. 代码重用:一个方法可以用于多种数据类型,避免为每种类型重载方法。 2. 类型安全:在编译时进行类型检查,避免了运行时类型转换错误。 3. 性能:避免了装箱拆箱(对于值类型)。 使用方法: 1. 定义方法:在方法名后面使用<T>(也可以多个类型参数,如<T, U>)来声明类型参数。 2. 可以在参数、返回类型方法体中使用这个类型参数T。 3. 可以添加约束(where子句)来限制类型参数,比如要求T必须是某个类的子类,或者具有无参构造函数等。 示例(根据引用[2][3]): 引用[2]中的例子:定义了一个方法GetInfo,它有一个类型参数T,并且对T有两个约束:必须是Test类(或子类)并且必须有无参构造函数。 引用[3]中的例子:定义了一个方法MyTest,它接受一个参数t,并打印该参数的值类型。 我们可以结合这些示例,并给出更详细的解释。 另外,用户上一次的问题是关于LINQ的Where扩展方法,但当前问题转向了方法,因此我们要专注于当前问题。 注意:回答中如果引用了站内的引用,需要在引用的段落末尾添加引用标识,如[^2]。 </think>### C# 函数中的使用方法作用 函数C# 中实现**类型安全代码复用**的核心技术,通过在函数定义中引入**类型参数**(如 `<T>`),使函数能动态适应不同数据类型,同时保证编译时类型检查。 #### 一、基本语法与定义 ```csharp // 定义函数 public T Process<T>(T input) { return input; // T 可以是任意类型 } // 使用示例 int num = Process(100); // 编译器推断 T 为 int string text = Process("Hello"); // T 为 string ``` - **类型参数标识符**:函数名后的 `<T>`(可多个,如 `<TKey, TValue>`) - **动态类型替换**:调用时编译器自动将 `T` 替换为具体类型[^3] #### 二、核心作用详解 1. **消除类型强转** 避免 `object` 类型导致的运行时错误装箱拆箱开销: ```csharp // 非方案(需强制转换) public object GetValue(object obj) => obj; int value = (int)GetValue(10); // 可能抛出 InvalidCastException // 方案(类型安全) public T GetValue<T>(T obj) => obj; int value = GetValue(10); // 编译时确定类型[^2] ``` 2. **实现通用算法** 编写一次逻辑即可处理多种数据类型: ```csharp // 交换函数 public void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; } // 支持任意类型交换 int x=1, y=2; Swap(ref x, ref y); // 交换整 string s1="A", s2="B"; Swap(ref s1, ref s2); // 交换字符串 ``` 3. **增强代码约束**(`where` 子句) 限制类型参数的能力,避免非法操作: ```csharp // 约束 T 必须有无参构造函数且实现 IComparable public T CreateAndCompare<T>() where T : new(), IComparable { T obj1 = new T(); T obj2 = new T(); return obj1.CompareTo(obj2) > 0 ? obj1 : obj2; // 编译器验证方法存在 } ``` - 常用约束: - `where T : struct`:值类型 - `where T : class`:引用类型 - `where T : new()`:有无参构造函数 - `where T : BaseClass`:继承基类[^2] #### 三、高阶用法 1. **反射结合** 动态创建类型实例: ```csharp public T CreateInstance<T>() where T : new() => new T(); ``` 2. **委托** 类型安全的回调机制: ```csharp public delegate T Transformer<T>(T input); public T[] TransformArray<T>(T[] array, Transformer<T> transformer) { for (int i=0; i<array.Length; i++) array[i] = transformer(array[i]); return array; } // 使用:将整数组元素加倍 int[] result = TransformArray(new[]{1,2,3}, x => x*2); ``` #### 四、性能优势对比 | 方案 | 类型安全 | 装箱拆箱 | 代码复用率 | |---------------|---------|----------|-----------| | `object` 参数 | ✗ | 高 | 中 | | 函数重载 | ✓ | 无 | 低 | | **函数** | ✓ | 无 | **高** | > 💡 **最佳实践**:当函数逻辑与具体类型无关时(如集合操作、数学运算),优先使用函数减少重复代码并提升类型安全[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值