Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass class type as parameter c# and used with dictionary

I am create a function to return a dictionary and I want to pass class name through as a parameter. But its gives an error. Code i have written is given below

public Dictionary<object, object> GetDetails(Type Classname)
{
    MvcDemoDBEntities db = new MvcDemoDBEntities();
    Dictionary<Classname, object> dict = new Dictionary<Classname, object>();

    var data = (from h in db.People
                select h).ToList();

    foreach (var item in data)
    {
        dict.Add(data, true);
    }
    return dict;
}

what am i doing wrong and i would like to call this function with a class name dynamically, like this :

List<people> list = GetDetails(people).Keys.ToList();

people its my class name.

like image 514
Nayeem Mansoori Avatar asked Nov 22 '13 10:11

Nayeem Mansoori


People also ask

How to pass a function as an object in C++?

In C++ 11, there is a std::function<> template class that allows to pass functions as objects. An object of std::function<> can be created as follows.

What is a type parameter?

In a generic type or method definition, a type parameters is a placeholder for a specific type that a client specifies when they instantiate a variable of the generic type.

How to pass a function as a parameter to another function?

In C++ 11, there is a std::function<> template class that allows to pass functions as objects. An object of std::function<> can be created as follows. Below is the program to illustrate the passing of a function object as a parameter to another function:

How to pass a type as an argument to a method?

You can pass a type as an argument, but to do so you must use typeof: The method would need to accept a parameter with type Type. where the GetColumns method will call a different method inside depending on the type passed. If you want this behaviour then you should not pass the type as an argument but instead use a type parameter.


2 Answers


Using Generics

Your current approach will give you much trouble. As you are going to pass a Type object for your class, you will need reflection to be able to create the Dictionary.

As an alternative, I propose to you to create a generic method:

public Dictionary<object, object> GetDetails<TClass>()
{
    MvcDemoDBEntities db = new MvcDemoDBEntities();
    Dictionary<TClass, object> dict = new Dictionary<TClass, object>();

    var data = (from h in db.People
            select h).ToList();

    foreach (var item in data)
    {
        dict.Add(data, true);
    }
    return dict;
}

Use it like this:

List<people> list = GetDetails<people>().Keys.ToList();

Using Type

Of course, this can be done using a Type object, this requiers the use of reflection to be able to create an object of which type we don't know (that object is the dictionary). This is done as follows:

public Dictionary<object, object> GetDetails(Type Class)
{
    //Null check
    if (null == Class)
    {
        throw new ArgumentNullException("Class");
    }

    MvcDemoDBEntities db = new MvcDemoDBEntities();

    //Get the generic dictionary type:
    Type DictType = typeof(Dictionary<,>).MakeGenericType(Class, typeof(object));

    //Create the dictionary object:
    object dict = Activator.CreateInstance(typeof(DictType));

    //Get the Add method:
    var add = DictType.GetMethod("Add", new Type[]{Class, typeof(object)});

    var data = (from h in db.People
            select h).ToList();

    foreach (var item in data)
    {
        //add to the dictionary:
        add.Invoke(dict, new object[]{item, true});
    }

    return dict;
}

Use like this:

List<people> list = GetDetails(typeof(people)).Keys.ToList();

Digging deeper

I notice you have this line:

var data = (from h in db.People select h).ToList();

You may be interested in changing People to a property matching the name of the class you pass in. This can only be archived via reflection. In a similar way as how we got the Add method of the dictionary, we can get a property from the object db which name is given by the argument type.

I'll present this as a second method to be called by the first.


Using Generics

public IEnumerable<TClass> GetCollection<TClass>(MvcDemoDBEntities db)
{
    //get the type of db
    var dbType = db.GetType();
    //get the name of the type TClass
    var name = typeof(TClass).Name;
    //get the property
    var prop = dbType.GetProperty(name);
    //read the property and return
    return prop.GetValue(db);
}

To use, replace this:

var data = (from h in db.People select h).ToList();

With this:

var data = (from h in GetCollection<TClass>(db) select h).ToList();

Using Type

Here the struggle is that we don't know the item type... so I'll use IEnumerable.

public IEnumerable GetCollection(MvcDemoDBEntities db, Type Class)
{
    //get the type of db
    var dbType = db.GetType();
    //get the name of the type Class
    var name = Class.Name;
    //get the property
    var prop = dbType.GetProperty(name);
    //read the property and return
    return prop.GetValue(db);
}

To use, replace this:

var data = (from h in db.People select h).ToList();

With this:

var data = (from h in GetCollection(db, Class).Cast<object>() select h).ToList();
like image 150
Theraot Avatar answered Oct 17 '22 02:10

Theraot


You need to use typeof to pass the type of your class

List<people> list = GetDetails(typeof(people)).Keys.ToList();
like image 32
Kamil Budziewski Avatar answered Oct 17 '22 02:10

Kamil Budziewski