2014-02-13 38 views
0

我将非常感谢任何帮助。我有一个字符串作为输入。我们称之为'table_name'。我想创建一个table_names的集合(其中table_name是被引用项目中的实际对象)。我做了以下内容:C#获取Generic对象的成员

Object obj = Activator.CreateInstance("ClassLibrary", "ClassLibrary." + table_name); 
Type CollectionType = typeof(Collection<>).MakeGenericType(new[] { obj.GetType() }); 
ICollection c = (ICollection)Activator.CreateInstance(CollectionType); 

然后我打电话的方法(它位于不同的项目,并且返回一个对象的集合),填补了我的ICollection对象(在这种情况下,C):

object[] parameters = new object[] { x_coord, y_coord, buffer_dist}; 
c = (ICollection)sde_db.GetType().GetMethod("Method" + table_name).Invoke(sde_db, parameters); 

到目前为止一切正常。我可以看到集合中元素的数量。但问题是,当我尝试遍历集合时,它不显示其元素。我只能在运行时看到它们。有没有办法在编译期间检索集合的成员?我想要类似:

for(int i = 0; i < c.Count; i++){ 
    label.Text = c[i].Details; 
} 

谢谢!

+0

是否有某些原因导致您无法正常声明集合?这看起来像是一个非常迂回的做法。 – Magus

+0

编译器不知道它们在编译时键入的是什么,运行时决定它。如果你在编译时知道,你不需要做这些反射。 –

+0

您定位的是C#的哪个版本? C#4.0和5.0具有动态对象。 – diegog

回答

0

因为我只需要关于ICollection中每个元素的详细信息,所以我使用System.Xml.Serialization来获取包含集合中特定元素信息的字符串。

for (int i = 0; i < c.Count; i++) 
     { 
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(c[i].GetType()); 
      using (StringWriter writer = new StringWriter()) 
      { 
       x.Serialize(writer, c[i]); 
       String details = writer.ToString(); 
      } 
        //do here what ever you want 
     } 
0

是的,但你必须回答什么成员在那里以及你打算如何使用它们(最重要的是,当你编写代码时,编译器知道你的意思,例如.Details)。例如。如果你的对象将始终贯彻一个接口...

public interface IHasDetails 
{ 
    string Details { get; } 
} 

然后你就可以把对象为该类型:

label.Text = ((IHasDetails)c[i]).Details; 

如果你只是想动态地访问它,使用dynamic

label.Text = ((dynamic)c[i]).Details; 
0

ICollection没有定义索引存取器,所以你不能做c[i]

难道你不能用IList代替吗?

0

为了在编译期间访问成员,您需要使用具有可用成员的具体类型。鉴于您动态访问涉及的类型,除非它们具有共同的,已知的基本类型或接口,否则这似乎不可行。如果没有这些机制之一,你就会减少某种动态访问。