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

时间:2014-10-23 21:58:25

标签: 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
          {
               toRemove.Add(n);
          }
     }
}

那么,检查房产的最优雅方式是什么?变量&#34; ? (变量是引用类型)

谢谢!

编辑:

节点的确定:

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

VariableNode的定义:

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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