You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何使用类型变量初始化泛型BaseClass类

问题:通过反射初始化泛型BaseClass并调用其方法

我对Reflection(反射)的理解还很粗浅。

abstract class BaseClass<T>
{
    public abstract T Value { get; }
    public virtual bool CheckValue(string input)
    {
        return true;
    }
}

class NotBaseClassA : BaseClass<string>
{
    public override string Value { get => "Yes";}
    public override bool CheckValue(string input)
    {
        return 1 == 2;
    }
}

class NotBaseClassB : BaseClass<int>
{
    public override int Value { get => 1; }
}

class ManyBaseClasses
{
    public NotBaseClassB notBaseClassB;
    public NotBaseClassA notBaseClassA;
}

class Programm
{
    public void Main()
    {
        foreach (PropertyInfo pi in typeof(ManyBaseClasses).GetProperties())
        {
            string input = Console.ReadLine();
            //Get the generic type of the propertyInfo
            //BaseClass<type> bt = new BaseClass<type>();
            //Instantiate BaseClass not as a var So I can do 
            //BaseClass.CheckValue(input)
        }
    }
}

我正尝试实现目标:使用类型变量初始化泛型BaseClass<T>。我看过相关回答,但返回的是var类型,我无法通过var调用CheckValue()方法(或者我认为不行)。我需要用类型变量对应的正确类型初始化BaseClass<T>,得到一个正式的BaseClass对象而非var,以便调用其方法。

补充说明:我已经通过以下自定义扩展方法获取到了泛型类型变量:

public static System.Type GetBaseClassType(this System.Type type)
{
    System.Type[] types = new System.Type[]{ };
    while (type != null && type != typeof(object) || types.Length == 0)
    {
        types = type.GetGenericArguments();
        
        if (types.Length > 0)
        {
            return types[0];
        }
        type = type.BaseType;
    }
    return null;
}

解决方案

核心注意点

你原代码里ManyBaseClasses中的是字段(public NotBaseClassB notBaseClassB;),不是属性,所以遍历的时候要用GetFields()而非GetProperties(),这是容易踩的坑。

方案一:引入非泛型基类(推荐)

给泛型BaseClass<T>添加一个非泛型抽象基类,让所有子类能统一向上转型,直接调用CheckValue方法:

// 添加非泛型基类,定义通用方法
public abstract class BaseClass
{
    public abstract bool CheckValue(string input);
}

// 修改泛型基类,继承自非泛型基类
abstract class BaseClass<T> : BaseClass
{
    public abstract T Value { get; }
    public override bool CheckValue(string input)
    {
        return true;
    }
}

之后在Main方法中直接转型调用:

class Programm
{
    public void Main()
    {
        var manyBaseInst = new ManyBaseClasses();
        foreach (FieldInfo fi in typeof(ManyBaseClasses).GetFields())
        {
            string input = Console.ReadLine();
            // 获取字段实例
            var instance = fi.GetValue(manyBaseInst);
            // 转为非泛型BaseClass,直接调用方法
            if (instance is BaseClass baseObj)
            {
                bool checkResult = baseObj.CheckValue(input);
                // 处理结果,比如输出
                Console.WriteLine($"检查结果:{checkResult}");
            }
        }
    }
}

方案二:直接通过反射调用方法(无需修改原类结构)

如果不想改动现有基类结构,直接用反射定位并调用CheckValue方法:

class Programm
{
    public void Main()
    {
        var manyBaseInst = new ManyBaseClasses();
        foreach (FieldInfo fi in typeof(ManyBaseClasses).GetFields())
        {
            string input = Console.ReadLine();
            var instance = fi.GetValue(manyBaseInst);
            // 获取CheckValue方法,参数类型为string
            MethodInfo checkMethod = instance.GetType().GetMethod("CheckValue", new[] { typeof(string) });
            if (checkMethod != null)
            {
                // 调用方法并转换返回值
                bool checkResult = (bool)checkMethod.Invoke(instance, new object[] { input });
                Console.WriteLine($"检查结果:{checkResult}");
            }
        }
    }
}

关于你的扩展方法

你的GetBaseClassType是用来获取泛型参数T的,但在调用CheckValue的场景下完全不需要用到它。如果后续需要处理Value属性,再结合这个方法获取泛型类型,通过反射读取属性值即可。


内容的提问来源于stack exchange,提问作者Logane Ramez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:50:24