преобразовать массив разных типов - PullRequest
1 голос
/ 22 марта 2011

У меня есть массив, который может содержать 1 из 3 типов (switch1, switch2, switch3). Как мне преобразовать это в список?

var switches = _switch.Switches;  
var newList = switches.Cast<SwitchObj>().ToList();

Это не сработало. Вот что есть в каждом из switch1, switch2, switch3

string DeviceType 
string Name
string[] State

Ответы [ 3 ]

3 голосов
/ 22 марта 2011

Тип ArrayList является рудиментарным артефактом дней до генериков. Вам больше не нужно его использовать и (если вы действительно этого хотите) вы можете просто создать List<object>. Конечно, это не решит вашу проблему, потому что вы пытаетесь привести два разнородных типа (string и string[]) к одному типу, что не имеет особого смысла.

Мой совет - хранить в коллекции только один тип объекта. Похоже, что все ваши типы будут соответствовать свойствам одного класса, так что ...

class Device
{
    public Device( string name, string type, string[] state = null )
    {
        Name = name;
        DeviceType = type;
        State = state;
    }

    public string Name { get; }
    public string DeviceType { get; }
    public string[] State { get; set; }
}

Теперь вам нужно всего лишь заполнить вашу коллекцию Device объектами, и все ваши проблемы с кастингом исчезнут.

List<Device> devices = new List<Device>();
devices.Add( new Device( "Device1", "SomeType" ) );
devices.Add( new Device( "Device2", "SomeType" ) );
devices.Add( new Device( "Device3", "SomeType" ) );

foreach( Device d in devices )
{
    // do stuff with d.Name, d.State, and d.DeviceType
}

РЕДАКТИРОВАТЬ для решения обновленного вопроса:

Либо оба типа совместимы, либо нет, обойти это невозможно. Поскольку это не так, можете ли вы изменить классы для реализации единого интерфейса? Например, если оба класса реализуют следующий интерфейс, вы можете просто поддерживать коллекцию List<IDevice> и обрабатывать их в общем. Итак, код становится примерно таким ...

interface IDevice
{
    string Name { get; }
    string DeviceType { get; }
    string[] State { get; set; }
}

class DeviceTypeOne : IDevice
{
    // constructor omitted

    public string Name { get; }
    public string DeviceType { get; }
    public string[] State { get; set; }
}

class DeviceTypeTwo : IDevice
{
    // constructor omitted

    public string Name { get; }
    public string DeviceType { get; }
    public string[] State { get; set; }
}

List<IDevice> devices = new List<IDevice>();
devices.Add( new DeviceTypeOne( "Device1", "SomeType" ) );
devices.Add( new DeviceTypeTwo( "Device2", "SomeType" ) );

foreach( IDevice d in devices )
{
    // do stuff with d.Name, d.State, and d.DeviceType
    // you now just deal with each object through the IDevice interface
}

Если вы не можете изменить код, вам просто придется иметь дело с ними отдельно в зависимости от их типа. Например:

IEnumerable<SomeDeviceType> lsOne = arrayList.OfType<SomeDeviceType>();
IEnumerable<SomeOtherDeviceType> lsTwo = arrayList.OfType<SomeOtherDeviceType>();
0 голосов
/ 22 марта 2011

Вместо использования Cast вы можете использовать OfType, который будет возвращать последовательность элементов, которые соответствуют указанному типу.Это эквивалентно Cast, но не выбрасывает, если предмет не соответствует.

В вашем случае, switches.OfType<SwitchObj>().ToList() будет List<SwitchObj>.Любые другие элементы в ArrayList будут игнорироваться.

0 голосов
/ 22 марта 2011

Вы можете разыграть, если все три типа имеют одинаковый базовый тип. Если ваши типы - строка, строка и строка [], то нет другого способа, кроме приведения к списку.

Чего вы пытаетесь достичь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...