仅获取继承类的父字段

发布于 2025-01-09 15:14:41 字数 1007 浏览 0 评论 0原文

我有一个名为 Stats 的类

public class Stats : ScriptableObject
{
    public double vitality;   
    public double stamina;     
    public double endurance; 
} 

我还有一个继承 Stats 的类

public class Equipment : Stats
{
    public string name;
    // other fields that define equipment
} 

我希望能够从继承自 Equipment 的 Stats 实例中获取所有字段

所以我将其添加到 Interface 类中

    public void AddStats(Equipment equippedItem)
    {
        Stats stats = equippedItem as Stats;
        if (stats != null)
        {
            GetPropertyValues(stats);
        }
    }
   public static void GetPropertyValues(System.Object obj)
   {
        Type t = obj.GetType();
        FieldInfo[] fis = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
        foreach (var fieldInfo in fis)
                Debug.Log(fieldInfo.FieldType + " " + fieldInfo.Name + " " + fieldInfo.GetValue(obj));
   }

问题是它正在获取所有字段以及设备中的字段。

我怎样才能做到只从统计数据中获取字段?

I have a class called Stats

public class Stats : ScriptableObject
{
    public double vitality;   
    public double stamina;     
    public double endurance; 
} 

I also have a class that inherits Stats

public class Equipment : Stats
{
    public string name;
    // other fields that define equipment
} 

I want to be able to get all the fields from the instance of Stats that is inherited from Equipment

So I added this in an Interface class

    public void AddStats(Equipment equippedItem)
    {
        Stats stats = equippedItem as Stats;
        if (stats != null)
        {
            GetPropertyValues(stats);
        }
    }
   public static void GetPropertyValues(System.Object obj)
   {
        Type t = obj.GetType();
        FieldInfo[] fis = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
        foreach (var fieldInfo in fis)
                Debug.Log(fieldInfo.FieldType + " " + fieldInfo.Name + " " + fieldInfo.GetValue(obj));
   }

The issue is that it is getting all the fields from the Equipment as well.

How could I make it so that only gets the fields from Stats?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℡Ms空城旧梦 2025-01-16 15:14:41

不要使用

Type t = obj.GetType();

但传入您的目标类型

typeof(Stats);

您可以对此用例进行重载,

public static void GetPropertyValues(System.Object obj, Type type)

并添加检查给定的 obj 是否为 type 类型或子类

var objType = obj.GetType();
if(objType != type && !objType.IsSubclassOf(type))
{
    throw ArgumentException($"Provided object of type {objType.Name} is not derived from {type.Name}");
}

或与泛型相同

public static void GetPropertyValues<Ttype>(System.Object obj)

var objType = obj.GetType();
var type = typeof(T);
if(objType != type && !objType.IsSubclassOf(type))
{
    throw ArgumentException($"Provided object of type {objType.Name} is not derived from {type.Name}");
}

反射永远不会“美丽”;)

Don't use

Type t = obj.GetType();

but pass in your target type

typeof(Stats);

You could have an overload for this use case and have e.g.

public static void GetPropertyValues(System.Object obj, Type type)

and add a check if the given obj is of type type or a subclass

var objType = obj.GetType();
if(objType != type && !objType.IsSubclassOf(type))
{
    throw ArgumentException(
quot;Provided object of type {objType.Name} is not derived from {type.Name}");
}

Or the same as a generic

public static void GetPropertyValues<Ttype>(System.Object obj)

and

var objType = obj.GetType();
var type = typeof(T);
if(objType != type && !objType.IsSubclassOf(type))
{
    throw ArgumentException(
quot;Provided object of type {objType.Name} is not derived from {type.Name}");
}

Reflection is never going to be "beautiful" ;)

您的好友蓝忘机已上羡 2025-01-16 15:14:41

我在这里找到了一个解决方案 如何在 C# 中使用反射获取自定义方法列表
所以我创建了一个名为 stat 的属性

[AttributeUsage(AttributeTargets.Field)]
public class Stat : Attribute {}

,并将此属性添加到我想要在 Stats 类中获取的所有变量:

    public class Stats : ScriptableObject
    {
        [Stat] public double vitality;   
        [Stat] public double stamina;     
        [Stat] public double endurance; 
    } 

然后我更新了 GetPropertyValues 方法来获取属性并将其添加到数组中。

   public static void GetPropertyValues(System.Object obj, double[] array)
   {
        // Getting the class
        Type t = obj.GetType();
        // Getting all the fields(Variables)
        FieldInfo[] fis = t.GetFields(BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public);

        int arrayLength = 0;
        // Iterating over all fields (variables)
        for (int i = 0; i < fis.Length; i++) 
        {
            // Filtering through the list and if the field(Variable) is marked with a Stat attribute adds it to array length
            arrayLength += i;
        }

        array = new double[arrayLength];

        // Iterating over all the fields (variables)
        for (int i = 0; i < fis.Length; i++) 
        {
            // Filtering through the list and if the field(Variable) is marked with a Stat attribute ....
            Stat attribute = Attribute.GetCustomAttribute(fis[i], typeof(Stat)) as Stat;

            if (attribute != null)
            {
                Debug.Log(fis[i].Name + " " + fis[i].GetValue(obj)); // The name of the flagged variable.
                array[i] = (Convert.ToDouble(fis[i].GetValue(obj)));
                Debug.Log(array[i]);
            }
        }
   }

I have found a solution here How to get custom a list of methods with reflection in C#
so I created a attribute called stat

[AttributeUsage(AttributeTargets.Field)]
public class Stat : Attribute {}

And I added this attribute to all the variables I wanted to get in my Stats class:

    public class Stats : ScriptableObject
    {
        [Stat] public double vitality;   
        [Stat] public double stamina;     
        [Stat] public double endurance; 
    } 

Then I updated my GetPropertyValues method to pick up the attributes and added it to an array.

   public static void GetPropertyValues(System.Object obj, double[] array)
   {
        // Getting the class
        Type t = obj.GetType();
        // Getting all the fields(Variables)
        FieldInfo[] fis = t.GetFields(BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public);

        int arrayLength = 0;
        // Iterating over all fields (variables)
        for (int i = 0; i < fis.Length; i++) 
        {
            // Filtering through the list and if the field(Variable) is marked with a Stat attribute adds it to array length
            arrayLength += i;
        }

        array = new double[arrayLength];

        // Iterating over all the fields (variables)
        for (int i = 0; i < fis.Length; i++) 
        {
            // Filtering through the list and if the field(Variable) is marked with a Stat attribute ....
            Stat attribute = Attribute.GetCustomAttribute(fis[i], typeof(Stat)) as Stat;

            if (attribute != null)
            {
                Debug.Log(fis[i].Name + " " + fis[i].GetValue(obj)); // The name of the flagged variable.
                array[i] = (Convert.ToDouble(fis[i].GetValue(obj)));
                Debug.Log(array[i]);
            }
        }
   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文