Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不知道泛型类型的情况下获取泛型类型对象的属性_C#_Generics_Types_Properties_Get - Fatal编程技术网

C# 在不知道泛型类型的情况下获取泛型类型对象的属性

C# 在不知道泛型类型的情况下获取泛型类型对象的属性,c#,generics,types,properties,get,C#,Generics,Types,Properties,Get,我需要查看泛型类型的对象的属性,而不知道具体类型: foreach(var n in Nodes) { if(n.GetType().GetGenericTypeDefinition() == typeof(VariableNode<>)) { if((n as VariableNode<>).Variable == myVar) //obviously this does not work {

我需要查看泛型类型的对象的属性,而不知道具体类型:

foreach(var n in Nodes)
{
     if(n.GetType().GetGenericTypeDefinition() == typeof(VariableNode<>))
     {
          if((n as VariableNode<>).Variable == myVar) //obviously this does not work
          {
               toRemove.Add(n);
          }
     }
}
那么,检查属性变量最优雅的方法是什么?变量是引用类型

谢谢

编辑:

节点的定义:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using KSPComputer.Types;
using KSPComputer.Connectors;
namespace KSPComputer.Nodes
{

    [Serializable]
    public abstract class Node
    {
        public SVector2 Position;
        public int InputCount
        {
            get
            {
                return inputs.Count;
            }
        }
        public int OutputCount
        {
            get
            {
                return outputs.Count;
            }
        }
        public FlightProgram Program { get; private set; }
        private Dictionary<string, ConnectorIn> inputs;
        private Dictionary<string, ConnectorOut> outputs;
        public KeyValuePair<string, ConnectorIn>[] Inputs
        {
            get
            {
                return inputs.ToArray();
            }
        }
        public KeyValuePair<string, ConnectorOut>[] Outputs
        {
            get
            {
                return outputs.ToArray();
            }
        }
        public Node()
        {
            Position = new SVector2();
            inputs = new Dictionary<string, ConnectorIn>();
            outputs = new Dictionary<string, ConnectorOut>();
        }
        internal virtual void Init(FlightProgram program)
        {
            Program = program;
            OnCreate();
        }
        protected void In<T>(string name, bool allowMultipleConnections = false)
        {
            var connector = new ConnectorIn(typeof(T), allowMultipleConnections);
            connector.Init(this);
            inputs.Add(name, connector);
        }
        protected void Out<T>(string name, bool allowMultipleConnections = true)
        {
            var connector = new ConnectorOut(typeof(T), allowMultipleConnections);
            connector.Init(this);
            outputs.Add(name, connector);
        }
        protected void Out(string name, object value)
        {
            ConnectorOut o;
            if (outputs.TryGetValue(name, out o))
            {
                if (o.Connected)
                {
                    o.SendData(value);
                }
            }
        }
        protected ConnectorOut GetOuput(string name, bool connected = true)
        {
            ConnectorOut o;
            if (outputs.TryGetValue(name, out o))
            {
                if (o.Connected || !connected)
                {
                    return o;
                }
            }
            return null;
        }
        protected ConnectorIn In(string name)
        {
            ConnectorIn o;
            if (inputs.TryGetValue(name, out o))
            {
                return o;
            }
            return null;
        }
        public void UpdateOutputData()
        {
            RequestInputUpdates();
            OnUpdateOutputData();
        }
        protected virtual void OnUpdateOutputData()
        { }
        protected virtual void OnCreate()
        { }
        protected void RequestInputUpdates()
        {
            foreach (var i in inputs.Values)
            {
                i.FreshData = false;
            }
            foreach (var i in inputs.Values)
            {
                if (!i.FreshData)
                {
                    i.RequestData();
                }
            }
        }
        public IEnumerable<Connector> GetConnectedConnectors()
        {
            return (from c in inputs.Values where c.Connected select c as Connector).Concat(from c in outputs.Values where c.Connected select c as Connector);
        }
        public IEnumerable<Connector> GetConnectedConnectorsIn()
        {
            return (from c in inputs.Values where c.Connected select c as Connector);
        }
        public IEnumerable<Connector> GetConnectedConnectorsOut()
        {
            return (from c in outputs.Values where c.Connected select c as Connector);
        }
    }
}
变量节点的定义:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KSPComputer;
using KSPComputer.Nodes;
using KSPComputer.Connectors;
using KSPComputer.Variables;
namespace KSPComputer.Nodes
{
    [Serializable]
    public class VariableNode<T> : ExecutableNode
    {
        internal Variable Variable { get; private set; }
        internal void SetVariable(Variable variable)
        {
            this.Variable = variable;
        }
        protected override void OnCreate()
        {
            In<T>("Set");
            Out<T>("Get");
        }
        protected override void OnExecute(ConnectorIn input)
        {
            Variable.Value = In("Set").Get<T>();
            ExecuteNext();
        }
        protected override void OnUpdateOutputData()
        {
            Out("Get", Variable.Value);
        }
    }
}

看起来您应该能够使用反射:

foreach(var n in Nodes)
{
     if(n.GetType().GetGenericTypeDefinition() == typeof(VariableNode<>))
     {
          if(n.GetType().GetProperty("Variable").GetValue(n, null) == myVar) 
          {
               toRemove.Add(n);
          }
     }
}

另一种解决方案是为VariableNode定义一个非泛型基类,然后您可以将非泛型属性放在那里,最后您可以轻松地将节点转换为基类或接口,并获取属性的值。拥有一个非泛型库是非常流行的做法。

您能提供一些关于该代码的更多上下文吗?我会建议使用泛型类型约束。。。但如果没有更多的上下文,我不确定这是否合适。遗憾的是,泛型类型约束不适用。你想看什么?Node和VariableNode的定义很好。这就可以编译了。出于兴趣,为什么GetValue需要n作为参数,即使它已经在n的属性上被调用了?PS:测试需要一段时间,我会在确认后尽快添加正确的答案@pixartist这是因为您得到的是PropertyInfo类型的对象,它对调用它的对象一无所知。GetValue表示从该类型的实例化对象获取该属性的值。是的,我考虑过,但这会使调用泛型方法成为***in、Out和Get中的难题。编辑:啊,好的,是的,非泛型基类。是的,但这会使事情复杂化。我更喜欢这里的反射法。