简体   繁体   中英

Create a Generic list of <T>

I want to create a method that will create a List of generic objects. Is it possible? Something like this:

public class Mtrl 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }        
    public string Aa { get; set; }
}

public class Trdr 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Address { get; set; }
    public string AFM { get; set; }
    public string Phone01 { get; set; }
    public string Aa { get; set; }
}

And then with a generic class to create my list:

public class GenericClass<T>
{        
    public List<T> GetData<T>()
    {
        List<T> myList = new List<T>();
        if (typeof(T) == typeof(Trdr))
        {
            myList.Add(new Trdr());//Error 1: cannot convert from Trdr to 'T'   
        }
        if (typeof(T) == typeof(Mtrl))//Error 2: cannot convert from Mtrl to 'T'    
        {
            myList.Add(new Mtrl());
        }
        return myList;
    }
}

My mistake. I will try to clarify more. The Classes Trdr,Mtrl etc will have many different properties. The Getdata method will take data from a web service via json and i want to create a List of Objects and return it Something like this:

public List<T> GetData<T>()
        {
            List<T> myList = new List<T>();
            if (typeof(T) == typeof(Trdr))
            {
                for (int i = 0; i < 100; i++)//fetch data from web api in json format
                {
                    Trdr NewObj = new Trdr();
                    NewObj.Aa = "...";
                    NewObj.AFM = "...";

                    myList.Add(NewObj);
                }
            }
            if (typeof(T) == typeof(Mtrl))
            {
                for (int i = 0; i < 100; i++)
                {
                    Mtrl NewObj = new Mtrl();
                    NewObj.Aa = "...";
                    NewObj.Name = "name ...";

                    myList.Add(NewObj);
                }
            }
            return myList;
        }
    }

I suggest extracting an interface (or even a base class ):

 //TODO: Since you have more than 2 classes, please check the common interface 
 public interface Idr {
   string Id   { get; set; }
   string Name { get; set; }
   string Code { get; set; }        
   string Aa   { get; set; }
 }

With all classes of interest implementing it:

public class Mtrl : Idr
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }        
    public string Aa { get; set; }
}

public class Trdr : Idr 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Aa { get; set; }

    public string Address { get; set; }
    public string AFM { get; set; }
    public string Phone01 { get; set; }
}

Now you can use List<Idr> collection; we want the class ( T ) that implements Idr to have a parameterless constructor as well ( new() ):

public class GenericClass<T> where T : Idr, new()
{        
    public List<T> GetData()
    {
        List<T> myList = new List<T>() {
          new T();
        };

        return myList;
    }
}

Sounds like you are trying to create a new list that contains some initial data, and you need to do this for many different types T .

If Mtrl and Trdr has nothing in common and are handled completely differently, consider simply using different methods to get each type of list:

GetDataMtrl(){
    var result = new List<Mtrl>();
    result.Add(new Mtrl());
    return result;
} // etc

Otherwise what you need is Type Constraints of Generic Parameters , that can tell the compiler more about what T is. Or rather what the different values of T must have in common. For example you can do

    public List<T> GetData<T>() where T : new()
    {
        List<T> myList = new List<T>();

        myList.Add(new T());

        return myList;
    }

To say that for T it has to be possible to do new T() . Then you can say GetData<Trdr>() to get a list that contains a single empty Trdr , as you code might seem to try to do.

Maybe you need to set some default values in the data. I notice the classes has a lot of variables in common. Then you might consider using inheritance to specify this commonality:

public class Mtrl 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }        
    public string Aa { get; set; }
}

public class Trdr : Mtrl
{
    public string Address { get; set; }
    public string AFM { get; set; }
    public string Phone01 { get; set; }
}

And then write generic code where T is either of the type Mtrl or its descendant class:

    public List<T> GetData<T>() where T : Mtrl
    {
        List<T> myList = new List<T>();
        T MtrlOrTrdr = new T();
        MtrlOrTrdr.Id = "my-new-id-";

        myList.Add(MtrlOrTrdr);

        return myList;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM