Преобразование типа массива в единственное число

В C# можно преобразовать тип массива в единственное число для использования с Activator.CreateInstance. Возьмите это, например:

void Main()
{
    var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
    var objects = new List<object>();

    foreach (var type in types)
    {
        // possibly convert type here? (from array to singular - type[] to type) 

        Debug.WriteLine($"{type}");
        objects.Add(Activator.CreateInstance(type));
    }
}

// Define other methods and classes here

public class ExampleClass
{
    public int X;
    public int Y;
}

Получает следующий вывод:

Вывод LINQPad


person wonea    schedule 20.09.2017    source источник
comment
Что вы хотите вернуть? Массив с нулевыми элементами? Массив с одним элементом? Экземпляр типа элемента массива? Что-то другое?   -  person Matthew Watson    schedule 20.09.2017
comment
Поправьте меня, если я ошибаюсь, но ваш код имеет мало общего с вашим вопросом. Вы спрашиваете о преобразовании типа массива, но в коде вы просто пытаетесь создать новый массив (используя отражение), что терпит неудачу, потому что вы не предоставили параметр конструктору массива - размер массива, который вы пытаешься создать.   -  person decPL    schedule 20.09.2017
comment
Возможен обман? stackoverflow.com/q/3419456/982149   -  person Fildor    schedule 20.09.2017


Ответы (3)


Если я правильно понимаю ваш вопрос, вам может понадобиться что-то подобное, используя Type.GetElementType() через отражение.

static void Main(string[] args)
    {

        var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
        var objects = new List<object>();

        foreach (var type in types)
        {
            var typeInstance = type.GetElementType();

            if (typeInstance != null)
            {
                Debug.WriteLine($"{typeInstance}");
                objects.Add(Activator.CreateInstance(typeInstance));
            }
            else
            {
                objects.Add(Activator.CreateInstance(type));
            }
        }
    }

   public class ExampleClass
   {
        public int X;
        public int Y;
   }
person MarkusE    schedule 20.09.2017

Если я правильно понял ваш вопрос, вы хотите получить базовый тип массива, верно? Это должно быть довольно просто со свойством IsArray типа, просто проверьте каждую запись в вашем списке следующим образом:

private static Type GetTypeOrElementType(Type type)
{
    if (!type.IsArray)
        return type;

    return type.GetElementType();
}

Кстати, если вы хотите создать новый массив этого конкретного типа, вы можете использовать Array.CreateInstance вместо Activator.CreateInstance

person Manfred Radlwimmer    schedule 20.09.2017

Нашел эти работы:

void Main()
{
    var types = new[] { typeof(ExampleClass), typeof(ExampleClass[]) };
    var objects = new List<object>();

    foreach (var type in types)
    {
        Debug.WriteLine($"{type}");
        objects.Add(type.IsArray
                    ? Activator.CreateInstance(type, 1)
                    : Activator.CreateInstance(type));
    }
}

// Define other methods and classes here

public class ExampleClass
{
    public int X;
    public int Y;
}
person wonea    schedule 20.09.2017