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

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

12.06.2013, 21:03. Просмотров 2426. Ответов 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();
        }
 
        //???
   }
}

http://www.cyberforum.ru/csharp-beginners/thread1215258.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2013, 21:03
Я подобрал для вас темы с готовыми решениями и ответами на вопрос "Динамические" структуры (C#):

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

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

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

Методом вычислить тип треугольника: "не существует", "тупоугольный", "прямоугольный", "остроугольный"
Помогите пожалуйста С помощью метода вычислить тип треугольника::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
438 / 297 / 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
438 / 297 / 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
438 / 297 / 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;. Выбор типа курсора...

Поиск в массиве. Ошибка "Оператор "&&" не может применяться к операндам типа "bool" и "double""
Найти номер последнего минимального элемента среди положительных четных...

Если ответ отличается от "да" или "нет" тогда программа должны писать "Ничего не понятно"
Программа работает так как мне нужно (оптимизация не интересует) есть только...


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

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

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