简体   繁体   中英

C# Get members of Generic object

I will highly appreciate any help. I have a string as an input. Let's call it as 'table_name'. I want to create a collection of table_names (where table_name is an actual object in a referenced project). I did the following:

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

Then I called a method (which is located in different project and which returns Collection of objects) to fill out my ICollection object (in this case, c):

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

So far everything works fine. I can see the number of elements in the collection. But the problem is when I try iterate through the collection, it doesn't show its elements. I can see them only during run time. Is there a way to retrieve members of the collection during compile time? I want something like:

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

Thanks!

Yes, but you have to answer the question of what members are there and how you plan to use them (and most importantly, how the compiler knows what you mean when you write the code referring to them, eg .Details ). Eg if your objects will always implement an interface...

public interface IHasDetails
{
    string Details { get; }
}

Then you can cast the object to that type:

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

If you just want to access it dynamically, use dynamic :

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

ICollection does not define an index accessor so you cannot do c[i] .

Can't you use an IList instead?

In order to access the members during compile time you need to be using a concrete type that has the members available. Given that your dynamically accessing the types involved this doesn't seem possible unless they have a common, and known, base type or interface. Without one of those mechanisms you are reduced to some kind of dynamic access.

Since I needed only details about each element in the ICollection, I used System.Xml.Serialization to get a string containing info on a particular element in the collection.

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
        } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM