Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/14: Рейтинг темы: голосов - 14, средняя оценка - 4.64
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
#1

"Динамические" структуры

12.06.2013, 21:03. Просмотров 2491. Ответов 12
Метки нет (Все метки)

Допустим, в зависимости от результата какого-либо условия, в методе создается массив одной из структур(их несколько)... как затем можно привести этот массив к массиву структур a или b в зав. от условия так, чтоб с ним можно было работать, как если бы это был "заранее известный" массив структур?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct a
{
    int d;
    int e;
}
 
struct b
{
    int f;
}
 
class Class
{
    void Method(int val)
   {
        object[] obj;
        if(val == 0) 
        {
             obj = new object[1] 
             obj[0] = new a();
        }
        else
        {
             obj = new object[1] 
             obj[0] = new b();
        }
 
        //???
   }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2013, 21:03
Ответы с готовыми решениями:

XML Request и ошибка "Недопустимая лексема "=" в объявлении класса, структуры или интерфейса"
Пишу отправку xml запроса,компилятор ругается. using System; using...

Ошибка "Недопустимая лексема "{" в объявлении класса, структуры или интерфейса"
Ошибка "Недопустимая лексема "{" в объявлении класса, структуры или...

Описать класс "поезд", содержащий поля "пункт назначения", "номер поезда", "время отправления"
Помогите пожалуйста с классом Описать класс «поезд», содержащий следующие...

Проблема при сравнении: "Оператор ">" не может применяться к операндам типа "Т" и "Т""
Добрый день , пишу сортировку , все делаю на основе Т , но вот в чем проблемма...

Методом вычислить тип треугольника: "не существует", "тупоугольный", "прямоугольный", "остроугольный"
Помогите пожалуйста С помощью метода вычислить тип треугольника::cry: 1) если...

12
Ithilgwau
26 / 26 / 1
Регистрация: 19.09.2012
Сообщений: 123
12.06.2013, 21:16 #2
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        interface IMyStruct
        {
        }
        struct A : IMyStruct
        {
            public int d;
            public int e;
        }
 
        struct B : IMyStruct
        {
            public int f;
        }
 
        class Class
        {
            private void Method(int val)
            {
                IMyStruct[] array;
                if (val == 0)
                {
                    array = new IMyStruct[1];
                    array[0] = new A();
                }
                else
                {
                    array = new IMyStruct[1];
                    array[0] = new B();
                }
 
                foreach (var s in array)
                {
                    if (s is A)
                    {
                        var a = (A) s;
                    }
                    else if (s is B)
                    {
                        var b = (B)s;
                    }
                }
            }
        }
Добавлено через 1 минуту
Можно конечно и без интерфейса, т.е. new object[1]. От этого ничего не изменится, но с интерфейсом правильнее.
1
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
12.06.2013, 21:30  [ТС] #3
блин, я точно так же сначала подумал... только смутило, что интерфейс фактически для галочки...
по-моему, я еще кое-что "придумал"... но это сначала еще проверить надо
0
Ithilgwau
26 / 26 / 1
Регистрация: 19.09.2012
Сообщений: 123
12.06.2013, 21:35 #4
Интерфейс в данном случае - это просто защита от самого программиста, что он не будет никаких левых структур пихать в массив, а только те, что наследуют от этого интерфейса. К тому же, в интерфейс можно вынести что-то общее, что есть и там и там, и тогда не придётся даже делать "is"

Ага, проверь, если что пиши, интересно

Кстати, у тебя эти структуры всё равно упаковываются, а значит лучше уж сразу написать class вместо struct.
0
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
13.06.2013, 10:17  [ТС] #5
вообще смысл в том, чтобы привести массив из объектов к массиву из структур, и затем использовать какую либо переменную для доступа к нему:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
struct a
{
    int d;
    int e;
}
 
struct b
{
    int f;
}
 
class Class
{
    void Method(int val)
   {
        object[] obj;
        if(val == 0) 
        {
             obj = new object[100];
             var asd = Class1.arr<a>(obj);
             //преобразования
        }
        else
        {
             obj = new object[10];
             var asd = Class1.arr<b>(obj);
             //преобразования
        }      
   }
}
 
class Class1
{
    public static T[] arr<T>(object[] obj) where T : struct
    {
        for (int i = 0; i < obj.Length; i++)
            obj[i] = new T();
        return obj.OfType<T>().ToArray<T>();
    }
}
но если надо будет вернуть какую либо из структур в качестве результата,или взять в кач-ве аргумента, то тут вероятно, без интерфейсов не обойтись...
0
Anklav
440 / 299 / 46
Регистрация: 23.01.2013
Сообщений: 633
Завершенные тесты: 2
13.06.2013, 10:32 #6
Я сегодня еще и по вашему прошлому вопросу придумал, вот что:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool c = true;
 
object array;
if (c) array = new a[15];
else array = new b[15];
 
if (array is a[]) ((a[])array)[0].n = 0;
if (array is b[]) ((b[])array)[0].c = 0;
 
public struct a
{
    public int n;
}
 
public struct b
{
    public int c;
}
1
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
13.06.2013, 11:06  [ТС] #7
к сожалению, не работает - "преобразование... ...невозможно"
0
Anklav
440 / 299 / 46
Регистрация: 23.01.2013
Сообщений: 633
Завершенные тесты: 2
13.06.2013, 11:25 #8
Как это не работает? У меня работает, компилируется все.

Вы точно объявляете object а не object[]? Ключевой момент именно это.

Кстати узнать длину такого массива можно так:
C#
1
2
3
4
5
object arr = new int[156];
for (int i = 0; i < ((Array)arr).Length; i++)
{
 
}
1
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
13.06.2013, 11:31  [ТС] #9
да уж, скобки решают

Добавлено через 37 секунд
а почему же надо так, а не иначе?
0
Anklav
440 / 299 / 46
Регистрация: 23.01.2013
Сообщений: 633
Завершенные тесты: 2
13.06.2013, 11:45 #10
Вообще вместо object можно написать сразу Array.

C#
1
Array arr = new int[156];
Это связано скорее всего с тем, что в object[] заранее определен размер ячейки, 4 или 8 байт ( в зависимости от разрядности процессора) т.к. тип ссылочный. А в его предке Array ( и object который является предком всех классов) он не определен, и определяется в момент выделения памяти.

Я могу ошибатся.
0
Ithilgwau
26 / 26 / 1
Регистрация: 19.09.2012
Сообщений: 123
13.06.2013, 15:03 #11
[QUOTE=WWWinplex;4713453]
C#
1
2
3
4
5
6
    public static T[] arr<T>(object[] obj) where T : struct
    {
        for (int i = 0; i < obj.Length; i++)
            obj[i] = new T();
        return obj.OfType<T>().ToArray<T>();
    }
Такой вариант конечно тоже имеет место, но он менее производительный, т.к. в ToArray<T>() происходит копирование всего массива. А т.к. у тебя структуры, а не классы, то происходит распаковка, копирование и упаковка каждой структуры. Если собираешься обращаться со структурами как с object'ами, сразу делай их классами, будет гибче и быстрее И, кстати говоря, у тебя получается, что "obj = new object[100];" и "var asd = Class1.arr<a>(obj);" - это разные массивы, и если изменить один, другой не изменится...
0
WWWinplex
24 / 24 / 1
Регистрация: 16.05.2012
Сообщений: 285
13.06.2013, 17:24  [ТС] #12
у меня проблема: есть класс, в нем есть "обобщенный член" элементов, реализующих опр. интерфейс. В статическом
методе класса создается экземпляр этого класса, на вход методу - некоторый аргумент. В зав. от его значения создается массив "обобщенных членов", приведенных к одному из типов, реализующих интерфейс, в зав. опять же от параметра. Этот массив изменяется, затем уже вызывается конструктор класса, на вход которому подается этот массив, но приведенный уже к интерфейсу... короче речь идет об даункасте и последующем апкасте(ну так как-то)... можно ли это упростить? массив получается довольно большой, и происходит это все довольно медленно, да и само по себе убого...
0
Ithilgwau
26 / 26 / 1
Регистрация: 19.09.2012
Сообщений: 123
13.06.2013, 18:08 #13
Лучше бы тебе вообще отойти от массивов и использовать List<T> и IEnumerable<T>. Апкаст у них делается сам по себе, т.к. они ковариативны.

Итак, ты можешь создать какие-то коллекции:
C#
1
2
var list1 = new List<MyClass1>();
var list2 = new List<MyClass2>();
Затем любую из этих коллекций, если нужно, можно преобразовать вот так (апкаст):
C#
1
IEnumerable<IMyInterface> collInterface = list1;
(при условии конечно, что MyClass1 и MyClass2 наследуют от IMyInterface).

И где надо ты можешь сделать даункаст:
C#
1
var collClass1 = collInterface.OfType<MyClass1>;
Массивы тоже ковариантны, но если использовать только IEnumerable<T>, то тебе не нужно будет вызывать всякие ToArray(). И ты сможешь как угодно этими коллекциями жонглировать.
1
13.06.2013, 18:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.06.2013, 18:08

Построить иерархию классов "Студент", "преподаватель", "персона", "заведующий кафедрой"
Построить иерархию классов: Студент, преподаватель, персона, заведующий...

Напишите программу, которая подсчитывает, сколько учащихся получило "2", "3", "4" и "5"
Помогите, пожалуйста, с решением следующей задачи: учащиеся сдают экзамены по...

Составить программу по управлению манипулятором "мышь". Выбор типа курсора организовать по нажатию на клавиши "q","w","r
Составить программу по управлению манипулятором &quot;мышь&quot;. Выбор типа курсора...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru