Разные типы данных в одном массиве

Здравствуйте. Задача следующая.
Есть разные типы данных (пока что только два). Эти типы данных представлены в виде классов MyClass1, MyClass2. Так же есть два массива под эти классы. Содержимое ячеек нужно отобразить на UserControlах. Соответственно, типов UserControlов будет тоже два. Но тогда придётся перебирать по два массива, что не есть хорошо.
Можно создать базовый класс MyBaseClass, сделать в нем переменную, отвечающую за тип данных и наследовать MyClass* от него. Тогда оба типа можно будет покласть в один массив.
А с UserControlами как такое сделать?

А чем они отличаются и что мешает с ними делать так?

Как контролу данные передаются и как выводятся?

Вообще лучше попробовать не

а например какую-нибудь функцию переопределяемую в наследуемых классах, которая возвращает данные в нужном виде.

Или если два типа контролов и они по-разному выводят разные свойства, то тогда после определения типа видимо надо просто кастовать к нужному наследуемому классу. В массиве тогда можно хоть object хранить и проверять через is. Или если с базовым классом, то можно в классах переопределять функцию создания контрола.

в каком смысле?

Ну контролам же тоже можно этот массив передать. Или так же наследовать контролы если это надо.

Но лучше наверно так, чтобы не разводить кучу проверок

Зачем? Контролы не должны ничего знать о массивах. В каждом контроле долнжа быть только ссылка на соответствующий ему класс данных из массива.

Не понял. Они же все должны быть наследованы от класса UserControl. Как иначе-то?

А вот про это вообще не понял. О чём речь?

Скорее всего можно унаследоваться от UserControl, а потом от этого класса свои юзерконтролы.

Но только для типа в контроле можно без этого в какой-нибудь Tag засунуть или


using System;
using System.Collections.Generic;
using System.Linq;

public abstract class UserControl
{
	public abstract string Render();
}

public abstract class BaseClass
{
	public abstract UserControl CreateControl();
}

public class MyClass1 : BaseClass
{
	public string Color;
	public int Count;

    public MyClass1(string color, int count)
    {
        Color = color;
        Count = count;
    }

    public override UserControl CreateControl()
	{
		var control = new UserControl1();
		control.Data = this;
		return control;
	}
}

public class MyClass2 : BaseClass
{
	public string Name;
	public double Weight;
	public DateTime DateOfBirth;

    public MyClass2(string name, double weight, DateTime dateOfBirth)
    {
        Name = name;
        Weight = weight;
        DateOfBirth = dateOfBirth;
    }

    public override UserControl CreateControl()
	{
		var control = new UserControl2();
		control.Data = this;
		return control;
	}
}

public class UserControl1 : UserControl
{
	public MyClass1 Data;

	public override string Render()
	{
		return $"{Data.Color} * {Data.Count}";
	}
}

public class UserControl2 : UserControl
{
	public MyClass2 Data;

	public override string Render()
	{
		return $"{Data.Name} | {Data.Weight} | {Data.DateOfBirth.ToString("dd.MM.yyyy")}";
	}
}

public class Program
{
	public static void Main()
	{
		var items = new List<BaseClass>
		{
			new MyClass1("Red", 42),
			new MyClass2("Alice", 70.5, new DateTime(1990, 6, 20)),
			new MyClass1("Blue", 64),
			new MyClass2("Bob", 90.6, new DateTime(1988, 4, 16)),
		};

		var controls = items.Select(it => it.CreateControl());

		foreach (var control in controls)
        {
			Console.WriteLine(control.Render());
        }
	}
}

Я имел ввиду, что UserControl должен быть вне класса, а ссылка на класс в нём.

В коде выше так и есть )

Тогда почему public override UserControl CreateControl() находится внутри класса MyClass2?

Ну так это ж просто создание контрола для этого класса.

Я не могу понять, в чем именно преимущество такого способа.

Не надо писать кучу ifов везде где надо сделать что-то в зависимости от типа.

А если надо будет проверить тип, то только через is?

Или поле как в первом посте, или is.

if (obj is MyClass1)
{
    ... new UserControl1();
}
else if (obj is MyClass2)
{
    ... new UserControl2();
}
else // упс, забыли добавить MyClass3 тут
{
    throw new Exception($"Unknown type {obj.GetType()}");
}

Тогда не вижу смысла так делать. Лучше отдельными массивами.