Rebecca
Rebecca

Reputation: 14402

How to convert a string to generic Type

I have a method that has a signature that looks like this:

public IList<T> GetReferenceData<T>(TransactionManager transactionManager = null)
{
    IList<T> collection;
    var cacheData = DataCacheManager.Instance.GetCacheItem(typeof(T).Name);
    if (cacheData != null)
    {
        collection = (IList<T>)cacheData;
    }
    else
    {
        collection = this.GetReferenceDataNoCache<T>(transactionManager);
        DataCacheManager.Instance.AddCacheItem(typeof(T).Name, collection);
    }

    return collection;
}

I have another method that allows me to pass in a string, which converts that string to the appropriate type. I then want to call the above method.

public IList GetReferenceDataByType(string referenceType)
{
        // this works and returns the appropriate type correctly
        var type = this.GetEntity(referenceType); 

        // now I'm stuck
        return this.GetReferenceData<?>();
}

What replaces the question mark?

Upvotes: 0

Views: 129

Answers (3)

Dennis
Dennis

Reputation: 37770

Looks like you should invert your approach.
Instead of calling generic methods from non-generic alternatives, your GetReferenceData and GetReferenceDataNoCache should be rewritten as non-generic ones:

public IList GetReferenceData(Type type, TransactionManager transactionManager = null)
{
   // ...
}

private IList GetReferenceDataNoCache(Type type, TransactionManager transactionManager = null)
{
   // ...
}

public IList<T> GetReferenceData<T>(TransactionManager transactionManager = null)
{
    return (IList<T>)GetReferenceData(typeof(T), transactionManager);
}

Look at your code: the only benefit from T in GetReferenceData<T> is typeof(T).
The rest of method is non-generic in fact.

Upvotes: 0

Magnus
Magnus

Reputation: 46919

If I understand your question correctly you want somethiong like this:

public IList GetReferenceDataByType(string referenceType)
{
        // this works and returns the appropriate type correctly
        var type = this.GetEntity(referenceType); 

        var method = this.GetType().GetMethod("GetReferenceData");
        var generic = method.MakeGenericMethod(type);
        return (IList) generic.Invoke(this, new object[] { null });
}

Note that IList<T> does not implement IList so that cast may fail.

Upvotes: 1

Related Questions