Как объединить списки для универсальной функции в C #? - PullRequest
0 голосов
/ 30 августа 2018

Надеюсь, вопрос не слишком запутанный, я пытался объединить разные типы списков в одну функцию без большого количества кода, но я не знаю как. Это сценарий:

У меня есть несколько классов (TClass1.cs, TClass2.cs, TClass3.cs, TClass4.cs, ...), все похожие так:

namespace Polly
{
    public class TClass1
    {
        public string Box1 { get; set; }
        public string Box2 { get; set; }
    }
}

Тогда я использую их как списки:

    public List<TClass1> List1 = new List<TClass1>(); 
    public List<TClass2> List2 = new List<TClass2>(); 
    public List<TClass3> List3 = new List<TClass3>(); 

И в настоящее время я использую их в Main.cs следующим образом:

public class Polly
{
    private void button1_Click(object sender, EventArgs e)
    {
        if (value == 1)
        {
            //100 rows calculating string f
            string f = List1.Box1;
        }
        else if (value == 2)
        {
            //100 rows calculating string f
            string f = List2.Box1;
        }
        else if (value == 3)
        {
            //100 rows calculating string f
            string f = List3.Box1;
        }
    }
}

Так как все списки в основном одинаковы и скопированы и вставлены, я бы хотел вычислить строку f только один раз следующим образом:

public class Polly
{
    private void button1_Click(object sender, EventArgs e)
    {
        if (value == 1)
        {
            GetString(List1);
        }
        else if (value == 2)
        {
            GetString(List2);
        }
        else if (value == 3)
        {
            GetString(List3);
        }
    }

    private string GetString(List<> ls)
    {
         //100 rows calculating string f
         string f = ls.Box1;
         return f;
    }
}

Единственная проблема в том, какой тип Списка я должен использовать, так как он меняется от списка к списку (TClass1, TClass2 и т. Д.)?:

 private string GetString(List<WHATDOIPUTINHERE?> ls){}

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Предполагая, что все эти классы имеют свойства Box1 и Box2, вы можете получить их все из базового класса

public abstract class BaseClass
{
    public string Box1 { get; set; }
    public string Box2 { get; set; }
}

public class Class1 : BaseClass
{
    public int AdditionalProp { get; set; }
}

public class Class2 : BaseClass
{
    public double YetAnotherlProp { get; set; }
}

public class Class3 : BaseClass
{ }

public class Class4 : BaseClass
{ }

Затем создайте массив списков, набранный как IEnumerable<BaseClass>[] (здесь с примерами данных):

public IEnumerable<BaseClass>[] _enumLists = new IEnumerable<BaseClass>[] {
    new List<Class1>{ new Class1 { Box1 = "a1" }, new Class1 { Box1 = "a2" }, new Class1 { Box1 = "a3" } },
    new List<Class2>{ new Class2 { Box1 = "b1" }, new Class2 { Box1 = "b2" }, new Class2 { Box1 = "b3" } },
    new List<Class3>{ new Class3 { Box1 = "c1" }, new Class3 { Box1 = "c2" }, new Class3 { Box1 = "c3" } },
    new List<Class4>{ new Class4 { Box1 = "d1" }, new Class4 { Box1 = "d2" }, new Class4 { Box1 = "d3" } },
};

Поскольку интерфейс объявлен как

public interface IEnumerable<out T> : IEnumerable

... он ковариантен и позволяет объединять списки только для чтения и перечисления.

Вы можете легко получить объединенную строку

private string GetString(int value)
{
    return String.Join(", ", _enumLists[value - 1].Select(item => item.Box1));
}

Тест:

Console.WriteLine(GetString(2)); // Prints: c1, c2, c3
0 голосов
/ 30 августа 2018

Каждый класс должен наследовать от интерфейса

interface IBox1
{
    string Box1 { get; set; }
}

Тогда ваши классы реализуют это:

public class TClass1 : IBox1
{
    public string Box1 { get; set; }
    public string Box2 { get; set; }

}

Тогда ваши списки могут быть производного типа:

List<TClass1> List1 = new List<TClass1>();

И вы можете добавить к нему объекты TClass1:

List1.Add(new TClass1());

И определение вашего метода должно быть расширено.

 private string GetString(List<Box1Interface> ls) {
        return "";
    }

и ваш вызов метода. Это включает приведение к интерфейсу перед вызовом.

GetString(List1.ConvertAll(x => (IBox1)x));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...