none
泛型 如何 使用子类的某个字段 RRS feed

  • 问题

  •     一个父类有两个子类,外界调用父类的 SaveAllBuES3<T>()方法,传入的泛型T,通过T类型判断,再给父类的es3Path这个字段赋值。

        提问:我不想用 if else 的方式,而是想通过T的类型判断,让父类的es3Path直接取到子类的es3Path的值。有什么好办法么?

    ============父类代码=============

    public class BuffInfo : BaseInfo
    {
        public  string es3Path;
    
        //public virtual string Es3Path { get => es3Path; set => es3Path = value; }
    
        public void SaveAllByES3<T>(int saverID, Dictionary<string, T> dictBuffInfo)
            where T:BuffInfo
        {
            if (typeof(T)==typeof(GeneralBuffInfo))
            {
                es3Path = GeneralBuffInfo.es3Path;
            }
            else if (typeof(T) == typeof(SoldierBuffInfo))
            {
                es3Path = SoldierBuffInfo.es3Path;
            }
            ES3.Save<Dictionary<string, T>>(saverID.ToString(), dictBuffInfo,es3Path);
        }

    ==============子类代码1=====================

    public class GeneralBuffInfo : BuffInfo
    {
        public new static string es3Path = Consts.ES3_Directory_Info + Consts.ES3_GeneralBuffInfo + ".es3";

    ==============子类代码2=====================

    public class SoldierBuffInfo : BuffInfo
    
    {
        public new static string es3Path = Consts.ES3_Directory_Info + Consts.ES3_SoldierBuffInfo + ".es3";
    
        //public override string Es3Path { get => base.Es3Path; set => base.Es3Path = value; }


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。


    2019年12月16日 3:17

答案

  • Hi 

    你使用以下的代码来代替if else语句。

     public void SaveAllByES3<T>(int saverID, Dictionary<string, T> dictBuffInfo)
                where T : BuffInfo
            {
                FieldInfo field = typeof(T).GetField("es3Path");
                es3Path = field.GetValue(null).ToString();
              
            }

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年12月16日 6:41
    版主

全部回复

  • Hi 

    你使用以下的代码来代替if else语句。

     public void SaveAllByES3<T>(int saverID, Dictionary<string, T> dictBuffInfo)
                where T : BuffInfo
            {
                FieldInfo field = typeof(T).GetField("es3Path");
                es3Path = field.GetValue(null).ToString();
              
            }

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年12月16日 6:41
    版主
  • 成功了,好神奇!

        不过想多问一句:有比较简单的类似的讲反射的教程么?


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。

    2019年12月17日 1:05
  • Hi 

    感谢您的反馈。

    如果你想学习反射,我建议你可以先看下MSDN官方文档Reflection (C#)

    顺便提一下,你可以标记你认可的回复为解决方案,这样方便其他人能够再遇到类似问题时能够快速解决问题。

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2019年12月17日 1:13
    版主
  •     不好意思,其实我问题还没完结,还需要进一步请教,所以没有“标记为答复”:

        我想让父类的字段es3Path一定要被子类的es3Path重写,但字段不能被重写。因此,只好给父类的es3Path添加了一个属性ES3Path,并把ES3Path设置为Virtual,子类重写了这个ES3Path,但是出错,说“NullReferenceException: Object reference not set to an instance of an object”。

        难道typeof(T).GetField("ES3Path") 方法对属性无效,只对字段生效?

    ===============父类==================

        public virtual string ES3Path
        { get; }

    ===============子类=================

        public override string ES3Path
        { get { return Consts.ES3_Directory_Info + Consts.ES3_SoldierBuffInfo + ".es3"; } }

    ===============调用=================

        public void SaveAllByES3<T>(int saverID, Dictionary<string, T> dictBuffInfo)
            where T : BuffInfo
        {
            FieldInfo fieldInfo = typeof(T).GetField("ES3Path");
            string es3Path = fieldInfo.GetValue(null).ToString();
            ES3.Save<Dictionary<string, T>>(saverID.ToString(), dictBuffInfo, es3Path);


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。


    2019年12月17日 1:39
  • Hi

    感谢您的反馈。

    如果你想通过反射去操作属性,你应当使用PropertyInfo而不是FiledInfo.

    下面是具体的代码,你可以试一下。

     public void SaveAllByES3<T>(int saverID, Dictionary<string, T> dictBuffInfo)
                where T : BuffInfo
            {
                Object instance = Activator.CreateInstance(typeof(T));
                PropertyInfo property = typeof(T).GetProperty("ES3Path");
                string es3Path = property.GetValue(instance,null).ToString();
    
            }

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年12月17日 2:03
    版主
  • 原来如此,反射还要根据被反射对象,选择FieldInfo/PropertyInfo,应该就是两种Info,没有其他Info了吧?

    调用方法我猜可以如下方代码这样使用,这么写有漏洞么?

    (instance as T).SaveAllByES3(saverID, dictBuffInfo);


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。

    2019年12月17日 2:38
  • Hi

    反射不仅仅只有FiledInfo和PropertyInfo,还有MemberIno,MethodInfo,typeinfo等等。

    我不确定你这样调用是否是对的,但我可以告诉你我是这样调用的。

    BuffInfo buffInfo = new BuffInfo();
    Dictionary<string, SoldierBuffInfo> test = new Dictionary<string, SoldierBuffInfo>();
    buffInfo.SaveAllByES3<SoldierBuffInfo>(1, test);

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2019年12月17日 2:47
    版主
  • 谢谢,但你这样写等于事先知道了对象的类型,没有利用泛型。收获很多,感谢!

    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。

    2019年12月17日 3:32