How to implement Find, FindAll, ForEach in iList as ListT. C #

0

Premise is for a development in Unity3D with C #

I have a serialized class called Tool.

namespace Game.Data{

    [Serializable]
    public sealed class Tool 
    {
      public int id;
      public string name;
    }
}

From another class I have created a method to add to a list, see below.

    // type == nombre de la lista genérica
    // data == Tool
    public void Add( string type , object data ) 
    {
        // var insert = dictionary[type] as List<Tool>
        var insert = dictionary [type] as IList; 

        insert.Add (data);

    }

Execution of the previous script.

Tool item = new Tool();
item.id = 0;
item.name = "sierra";

Add( "Tool" , item );

dictionary [type] is a object that can become a List Tool >, but I discovered that with IList I do not need to implement the generic variable List < T > - It's great because I can automate my list - and execute the Add method;

My goal is to create an interface or to somehow make the Find, FindAll, ForEach methods of List < T > in iList.

Attached to the text is the method to create a dictionary with dynamic list.

public List<TypeItem> types; // Tipos de items
public List<Tool>     tools 

// Diccionario dinámico
Dictionary<string, object> dictionary;

void DynamicList()
{
    dictionary = new Dictionary<string, object> ();

    // Añadir listas al diccionario
    dictionary.Add("Tool", tools);  
    dictionary.Add("Type", types);      

}
    
asked by dGame 01.09.2017 в 11:26
source

1 answer

4

I'm sorry, but my answer is going to be aimed at convincing you that what you're trying is a bad idea. If I finally understand what you want to achieve, it's about having a Dictionary<string,object> where to store all your lists of different types with a key. I advise against doing it, since it is uncomfortable to handle and it is quite likely that you will have problems at some point. C # is a strongly typed language and avoids this kind of thing.

The problem is that with C # you can not perform a Cast to a known type at run time. That is, in your case, having a variable of type string with the name of the type (Tool for example) it is not possible to change an object of type IList<object> to List<Tool> .

Using Convert.ChangeType you can change the type to another, but since the compiler is not able to infer the type, you can not access the methods specific to the class List .

Questions in your comments:

  

Can do this: dictionary [type] .GetType (). GetMethod ("FindAll"). Invoke (dictionary [type], null). But FindAll requires a Predicate and I do not know how to implement it.

The problem is that the predicate goes to the end to need to access the underlying type of the list (for example, we take this lambda: x=>x.id==1 .) As the compiler knows that x has a property id if you do not know the type ??)

In short, maybe you could implement what you want with a lot of work, but it's something that does not make much sense. In the end almost any solution will be based on Reflection , which is not very advisable.

The only simple solution I see is to have some type of switch that at the end makes the correct% Cast :

string tipo = "Tool";

var listatool = dictionary[tipo] as System.Collections.IList;
switch (tipo)
{
    case "Tool":
          ((List<Tool>)listatool).Find(x => x.id == 1);
           break;
    //case "OtroTipo":
    //     ((List<OtroTipo>)listatool).Find(x => x.propiedad == 1);
    //     break;
    
answered by 01.09.2017 / 14:13
source