簡體   English   中英

C# 如何使用類型變量初始化通用 Class

[英]C# How To Initialize a generic Class with a type variable

免責聲明我是理解反射的新手。

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)

            }
        }
    }

我只是想像標題所說的那樣做。 所以我看到了這個答案,但答案返回了一個“var”,但我不能從類型 var 中調用我的 CheckValue() function。 (或者我認為我不能?)。 我需要的是從類型變量中使用正確的類型而不是作為 var 實例化我的 BaseClass<> 作為正確的 BaseClass obj,這樣我就可以調用我的函數。

編輯1:我已經設法通過做類似的事情來獲得變量中的泛型類型

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;
        }

基礎 class 在這種情況下不相關,因為它是抽象的,因此您實際上想要實例化派生的 class。

創建它所需要做的就是

Activator.CreateInstance(pi.PropertyType)

然后您將需要對該結果使用反射來調用CheckValue ,因為沒有通用的基本類型或接口。

將非通用代碼提取到非通用的BaseBaseClass中可能更容易,這意味着您不需要第二步的反射。

abstract class BaseBaseClass
{
    public virtual bool CheckValue(string input)
    {
        return true;
    }
}

abstract class BaseClass<T> : BaseBaseClass
{
    public abstract T Value { get; }
}

然后你可以做

((BaseBaseClass) Activator.CreateInstance(pi.PropertyType)).CheckValue(someInput)

我以前做過,但那是很久以前的事了。 您必須通過反射創建實例並通過反射調用該方法。

        foreach (PropertyInfo pi in typeof(ManyBaseClasses).GetProperties())
        {
            string input = Console.ReadLine();
            //Get the generic type of the propertyInfo
            var propType = pi.Type;
            Type[] typeArgs = { propType };
            var genType = d1.MakeGenericType(typeArgs);
            //BaseClass<type> bt = new BaseClass<type>();
            object bt = Activator.CreateInstance(genType);
            //Instantiate BaseClass not as a var So I can do 
            //BaseClass.CheckValue(input)
            MethodInfo method = typeof(bt).GetMethod("CheckValue"));
            method.Invoke(bt, new[] { input });
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM