Alexander Sokol
Alexander Sokol

Reputation: 681

How to cast object to type known only at runtime

Consider the following situation. I have a Dictionary<string,string> dictionary, and a string key. I do not know these two types at compile time, but I do know them at runtime. So at compile time, they're just objects. I'd like to make the call dictionary.ContainsKey(key). However, because key is a string "cast to an object", this yields a RuntimeBinderException. I'd like to understand how to resolve this issue.

Here are some tests demonstrating the issue:

    [TestMethod]
    public void ThisTestFails()
    {
        dynamic dictionary = getDict();
        var key = getKey();

        bool result = dictionary.ContainsKey(key);
        Assert.IsTrue(result);
    }

    [TestMethod]
    public void ThisTestWorks()
    {
        dynamic dictionary = getDict();
        var key = (string)getKey();

        bool result = dictionary.ContainsKey(key);
        Assert.IsTrue(result);
    }

    private object getDict() => new Dictionary<string, string>() { { "abc", "def" } };
    private object getKey() => "abc";

ThisTestFails fails with a RunTimeBinderException, while ThisTestWorks passes. So, what's happening is that while the key variable in both tests contains a string, its apparent type in ThisTestFails is an object, which can't be used in dictionary.ContainsKey.

What I need to resolve this, essentially, is a way to "cast" the key variable to a string at runtime. The (string)key solution in ThisTestWorks won't be useful to me, as I in the general case don't know the type of the dictionary key at compile time. What can be done to solve the issue?

Upvotes: 2

Views: 258

Answers (1)

Lukasz Cokot
Lukasz Cokot

Reputation: 450

Hi I think You are looking for something like this

dynamic dictionary = getDict();
dynamic key = getKey();

bool result = (bool)dictionary.ContainsKey(key);
Assert.IsTrue(result);

But here might be another problem because You are trying to look for a string which is boxed in 'object' type(this type is returned from your methods like GetKey()) so in containKey method comparison will be done as for object type meaning by reference not by value as for string.

Upvotes: 2

Related Questions