Using C# dynamic method for an object
Asked Answered
A

2

6

I have a method that should return the ids from a List. Usually I would use reflection for this task (I cannot use a generic method since the classes are usually POCOS that don't share an interface or a base class and I can't modify them). However, I thought about the new dynamic keyword and wanted to try this.

However my problem is that dataSource[index] returns an object. Well at runtime it is ensured that the object isself is on of my own classes and has a id property. But I suppose because the method returns an object, I get a RumtineBinderException at runtime while accessing current.id

public List<int> GetItemIds()
{

    var result = new List<int>();
    var dataSource = GetDataSource(); // returns an List<Object>

    for (int i = 0; i <= dataSource.Count - 1; i++)
    {
        dynamic current = dataSource[i];
        int id = current.Id;  // throws RuntimeBinderException: Object has no definition for id
    }

    return result;
}

Is there a way to achive what I want or do I have to go back to reflection to get the id property?

Update:

current.GetType() returns object
current.GetType().GetProperties() returns a TargetInvocationException

My Pocos live in my main project (VB.net) but this method is in a class libary, maybe that is the cause. However:

object current = dataSource[i];
PropertyInfo prop = current.GetType().GetProperty("id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (prop != null)
{
    int id = (int)prop.GetValue(current, null);
}

works.

Architectural answered 14/7, 2011 at 15:28 Comment(4)
what is current.GetType()? Is it the type you expect?Langdon
There is something wrong here....using dynamic in the example above should make it work if the runtime type has an Id property...Millardmillboard
It should work - can you update the post with the information for current.GetType(), and current.GetType().GetProperties()?Conurbation
I updated my question. current.GetType().GetProperties() throws an exception. but in the watch window I see all my properties.Dorri
C
1

I believe you may need to define the return type of "GetDataSource()" as "List<dynamic>".

Of course, as stated in the comments, the objects must have the property "id" defined.

Caesarea answered 14/7, 2011 at 15:36 Comment(1)
While my guess is that you wouldn't break anything by GetDataSource() as List<dynamic> because it technically compiles into List<object> with type checking, it just looks bad because Lists aren't covariant because you couldn't do same for example if List<SomethingElse> was returned. Either way it's not the solution because you are still telling the compiler to treat the returned object of the index as dynamic so there should be no difference.Compressibility
C
1

C# is case sensitive including when you use the dynamic keyword. your call is int id = current.Id; but you talk about the property being lowercase id, and your reflection call looks case insensitive. The dynamic keyword should have no problem calling public instance properties even across assembly boundaries, since it says the method is not found my best guess is that you need to be using int id = current.id;

Compressibility answered 18/7, 2011 at 13:40 Comment(1)
In my real world application the property is lowercase and I used ´current.id´ to access it to. (but I mixed it up in the example code). However, even if I see the property in the watch window accessing it by code failes.Dorri

© 2022 - 2024 — McMap. All rights reserved.