Gabriel
Gabriel

Reputation: 688

C# - How to pass a type as a parameter

I think it's more difficult to ask than answering the question. I wanna ask my question with an example: You know that we can bind an object to a DataSource, and that object could be of any type. So suppose I've bound an object of type "MyClass" to DataSource of a DataSet. Now I send this dataset as a parameter to another class in another DLL, and in this DLL file I want to create a List<> of type of "MyClass". As I have not access to "MyClass" type i can use this code to get the type of DataSource:

_dataSet.DataSource.GetType()

but I can't use the code like the following to create a List of type of "MyClass": List<_dataSet.DataSource.GetType()> _list;

What should I do in this situation?

Upvotes: 0

Views: 1495

Answers (5)

Dr. Wily&#39;s Apprentice
Dr. Wily&#39;s Apprentice

Reputation: 10280

You could use reflection, as other answers have pointed out.

Do you have control over the other class in the other DLL? Can you make that class or the particular method that you're calling on that class generic?

public class SomeOtherClassInSomeOtherDLL
{
    public void DoSomethingWithData<T>(T dataSource)
    {
        // ...

        List<T> list = new List<T>();
        list.Add(dataSource);

        // ...
    }
}

So you would call it like this:

        var anotherClass = new SomeOtherClassInSomeOtherDLL();

        // ...

        anotherClass.DoSomethingWithData(_dataSet.DataSource as MyClass);

Upvotes: 0

Nicholas Carey
Nicholas Carey

Reputation: 74177

You'll need to use reflection to instantiate a generic list of the desired type. This method should do the trick:

public object InstantiateGenericList( Type nodeType )
{
    Type   list        = typeof(List<>) ;
    Type   genericList = list.MakeGenericType( nodeType ) ;
    object instance    = Activator.CreateInstance( genericList ) ;

    return instance ;
}

Upvotes: 0

Ondrej Tucny
Ondrej Tucny

Reputation: 27962

There are basically two options:

  1. stick with List<object> or, better, we the closest known ancestor type of _dataSet.DataSource
  2. or use a nasty reflection hack to instantiate a List<T> dynamically.

I'd personally resort to option (1) in most cases because it is:

  • easier to use,
  • readable,
  • sufficiently type safe,
  • universal in terms of natural code reuse.

The second option was already elaborated in other answers.

Upvotes: 1

jason
jason

Reputation: 241585

You can dynamically create a generic type using reflection:

var listType = typeof(List<>).MakeGenericType(
    new[] { _dataSet.DataSource.GetType() }
);
var ctor = listType.GetConstructor(new Type[] { });
var list = ctor.Invoke(null);

Note that list will be typed as object.

Upvotes: 0

jvanrhyn
jvanrhyn

Reputation: 2824

var newtype = typeof (List<>).MakeGenericType(_dataSet.DataSource.GetType());
var _list = Activator.CreateInstance(newtype);

Upvotes: 0

Related Questions