Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223

Переменное количество параметров для типовой формы редактирования

29.04.2019, 22:57. Показов 3625. Ответов 23

Студворк — интернет-сервис помощи студентам
Добрый день!
Хочется сделать следующее. Есть несколько типовых форм редактирования сущностей. Конструкторы классов этих форм принимают в качестве параметра объект - саму сущность.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SomeEditForm1
{
SomeType1 Obj{get; set;}
  public SomeEditForm1(SomeType1 obj)
{
Obj = obj;
}
}
class SomeEditForm2
{
SomeType2 Obj{get; set;}
  public SomeEditForm2(SomeType2 obj)
{
Obj = obj;
}
}
Форму редактирования любой сущности вызываю общим методом:
C#
1
2
3
4
5
6
public static void LoadFormForEditing(Table Table, params object [] args)
        {
            object apf = Activator.CreateInstance(Table.ProjectEntity.typeOfForm, args);
            MethodInfo mi = Table.ProjectEntity.typeOfForm.GetMethod("ShowDialog", new Type[] { });
            mi.Invoke(apf, null);
        }
И вот, мне необходимо передать в форму несколько параметров. Делаю так:
C#
1
2
3
4
5
6
7
8
9
10
11
class SomeEditForm2
{
SomeType2 Obj2{get; set;}
SomeType3 Obj3{get; set;}
 
  public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null)
{
Obj2 = obj2;
Obj3 = obj3;
}
}
Теперь при попытке передать во вторую форму object [1] {someObj} - возникает ошибка, что у формы2 нет такого конструктора. Почему так? Почему если в конструкторе один параметр, то при передаче в качестве параметра массива объектов длиной в 1, всё нормально?

Понимаю, что можно сделать так:
C#
1
2
3
4
5
6
7
8
9
10
11
class SomeEditForm2
{
SomeType2 Obj2{get; set;}
SomeType3 Obj3{get; set;}
 
  public SomeEditForm2(params object[] args)
{
Obj2 = (SomeType2) args[0];
Obj3 = (SomeType3) args[1];
}
}
Но мне не нравится этот способ, есть ли варианты обобщения?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.04.2019, 22:57
Ответы с готовыми решениями:

Составить функцию, принимающую переменное количество параметров
Напишите и протестируйте шаблонную функцию с переменным числом аргументов sum_values(), которая принимает список произвольной длины с...

Создайте функцию, которая принимает переменное количество входных аргументов и возвращает переменное количество выходных
Создайте функцию, которая принимает переменное количество входных аргументов и возвращает переменное количество выходных аргументов....

Создайте функцию, которая принимает переменное количество входных аргументов и возвращает переменное количество
Помогите исправить ошибку в коде. Задание такое: Создайте функцию, которая принимает переменное количество входных аргументов и...

23
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
29.04.2019, 23:06
wrq2017, не знаю точно - Студию запускать лень.

Но на мой взгляд вот эти два конструктора public SomeEditForm2(SomeType2 obj) и public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null) будут конфликтовать. Уберите значение по умолчанию во втором.
2
3566 / 2507 / 1174
Регистрация: 14.08.2016
Сообщений: 8,219
30.04.2019, 01:25
только я вижу под одним названием 2 разных по и сути и по сигнатуре класса?
Цитата Сообщение от wrq2017 Посмотреть сообщение
class SomeEditForm2
{
SomeType2 Obj{get; set;}
* public SomeEditForm2(SomeType2 obj)
{
Obj = obj;
}
}
Цитата Сообщение от wrq2017 Посмотреть сообщение
class SomeEditForm2
{
SomeType2 Obj2{get; set;}
SomeType3 Obj3{get; set;}
public SomeEditForm2(params object[] args)
{
Obj2 = (SomeType2) args[0];
Obj3 = (SomeType3) args[1];
}
}
тупенький я, не вижу корреляции
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 08:40  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но на мой взгляд вот эти два конструктора public SomeEditForm2(SomeType2 obj) и public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null) будут конфликтовать. Уберите значение по умолчанию во втором.
Так это... Я предполагал оставить один конструктор из двух.

Добавлено через 15 минут
Цитата Сообщение от Diamante Посмотреть сообщение
тупенький я, не вижу корреляции
Может быть я не очень понятно объяснил. Первый класс - это начальное решение. Потом в эту форму понадобилось передавать не один, а два параметра (вообще хочется не зависеть от конкретного количества передаваемых параметров). Причем можно сказать, что первый параметр основной (редактируемый объект), а остальные вспомогательные - в некоторых случаях передаваться не будут и удобнее было бы задавать им значение по умолчанию null.
Второй класс - один из вариантов решения моей проблемы, который мне не нравится, потому что в данном случае конкретный параметр зависит от его места в массиве входных параметров, что плохо. Я бы предпочел вариант:
C#
1
2
3
4
5
6
7
public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null, SomeType4 obj4 = null, ....)
{
Obj2 = obj2;
Obj3 = obj3;
Obj4 = obj4;
....
}
но он вызывает ошибку и я понимаю почему, но не знаю как написать правильно. Есть ли какая-то возможность "на лету" разбивать входящий массив params object[] на конкретные объекты?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 09:19
Цитата Сообщение от wrq2017 Посмотреть сообщение
Я бы предпочел вариант:
C#
1
2
3
4
5
6
7
public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null, SomeType4 obj4 = null, ....)
{
Obj2 = obj2;
Obj3 = obj3;
Obj4 = obj4;
....
}
но он вызывает ошибку и я понимаю почему
Цитата Сообщение от wrq2017 Посмотреть сообщение
Теперь при попытке передать во вторую форму object [1] {someObj} - возникает ошибка,
Вы как-то очень непонятно объясняете.

Конструктор с одним обязательным параметрам типа SomeType2 и несколькими необязательными параметрами иных разных типов - объявлен у Вас корректно.

А что за ошибка у Вас возникает - не понятно. Может Вы хотите передать параметры не через запятую, а в одном массиве object [1] {someObj}?
Ну так объявите конструктор с массивом. Что этому мешает? Только надо реализовывать через статический метод, так как если в массиве будет отсутствовать обязательный параметр или конфликт типов параметров, то объект создаваться не должен.
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 09:33  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вы как-то очень непонятно объясняете.
Очень может быть
В данном случае - класс - это класс формы редактирования, она создается в любом случае. Правильно ли я понимаю, что в таком случае статический метод не нужен. То есть в настоящий момент делаю так:
C#
1
2
3
4
5
6
public PriceF(params object[] args)
{
  InitializeComponent();
  Price = (Price)args[0];
  if (args.Length > 1) FirstTypeOfPrice = (TypeOfPrice) args[1];
}
Что мне не очень нравится. Есть альтернативы?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 09:56
Цитата Сообщение от wrq2017 Посмотреть сообщение
Правильно ли я понимаю, что в таком случае статический метод не нужен.
Статический метод нужен, если необходима проверка параметров и при их некорректности объект создавать не нужно.
Если напрямую обращаться к конструктору с передачей некорректных параметров, то избежать создания ненужного объекта не получится. Конструктор всегда создаёт объект.

Цитата Сообщение от wrq2017 Посмотреть сообщение
То есть в настоящий момент делаю так:
Я не совсем понял Вашу идею, что Вы хотите реализовать.

В Ваших примерах Вы показывали конструкторы с передачей параметров каждого разного типа. Из них один обязательный.

Если я правильно понял, можно сделать так

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static PriceF Create (params object[] args)
{
     Ienumerable<SomeType1> someType1 = args.OfType<SomeType1>(); // Получение всех SomeType1
     SomeType1 some1; // Переменная для хранения обязательного параметра
     if (someType1== null || someType1.Count() !=1) // Проверка наличия и количества SomeType1 в полученных данных
             return nul; // Выход без создания объекта
     else
             some1 = someType1.First(); // Запись в переменную найденного обязательного параметра
 
     /// Дальше проверка остальных типов и параметров
 
 
    /// Если все проверки прошли успешно, то возврат объекта
    return new PriceF(some1, some2, some3, ....);
}
Добавлено через 6 минут
Цитата Сообщение от wrq2017 Посмотреть сообщение
И вот, мне необходимо передать в форму несколько параметров.
Если надо передать в метод какие-то обязательные параметры и неизвестное количество необязательных, то можно сделать так
C#
1
2
3
4
public static PriceF Create (SomeType1 some1,  params object[] args)
{
    /// Тело метода
}
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 10:50  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Статический метод нужен, если необходима проверка параметров и при их некорректности объект создавать не нужно.
Спасибо за методику, буду при необходимости применять. В данном случае форма редактирования создается в любом случае.

Задам свой вопрос по другому. Почему если класс имеет конструктор:
C#
1
2
3
4
5
6
7
8
class SomeEditForm2
{
SomeType2 Obj{get; set;}
  public SomeEditForm2(SomeType2 obj)
{
Obj = obj;
}
}
и мы его создаем объект вот так:
C#
1
obj = SomeEditForm2(new Object[1] {someObj});
то это возможно - преобразование массива объектов единичной длины в объект определенного типа не вызывает никаких проблем. Если конструктор переделать:
C#
1
2
3
4
5
6
7
public SomeEditForm2(SomeType2 obj2, SomeType3 obj3 = null, SomeType4 obj4 = null, ....)
{
Obj2 = obj2;
Obj3 = obj3;
Obj4 = obj4;
....
}

и создавать объект таким же образом
C#
1
obj = SomeEditForm2(new Object[1] {someObj});
это будет вызвать ошибку? Ведь значение второго параметра можно взять по умолчанию?

Добавлено через 1 минуту
P.S.
Сигнатура метода вызова общая, ее менять не могу:
C#
1
2
3
4
5
6
public static void LoadFormForEditing(Table Table, params object [] args)
        {
            object apf = Activator.CreateInstance(Table.ProjectEntity.typeOfForm, args);
            MethodInfo mi = Table.ProjectEntity.typeOfForm.GetMethod("ShowDialog", new Type[] { });
            mi.Invoke(apf, null);
        }
0
880 / 559 / 291
Регистрация: 21.11.2012
Сообщений: 1,554
30.04.2019, 11:10
какой смысл создавать массив, зная что в нем только один объект?
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 11:12
Цитата Сообщение от wrq2017 Посмотреть сообщение
и мы его создаем объект вот так:
.......
Цитата Сообщение от wrq2017 Посмотреть сообщение
то это возможно - преобразование массива объектов единичной длины в объект определенного типа не вызывает никаких проблем. Если конструктор переделать:
Что-то у Вас не так. Ошибка должна возникать и при конструкторе с одним параметром.
Где-то у Вас определён конструктор принимающий массив.

Смотрите скриншот.
Миниатюры
Переменное количество параметров для типовой формы редактирования  
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 11:18  [ТС]
Цитата Сообщение от hamin Посмотреть сообщение
какой смысл создавать массив, зная что в нем только один объект?
Дык массив и был создан, чтобы передавать большее количество параметров, нежели 1.

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Где-то у Вас определён конструктор принимающий массив.
Соль видимо в params object [] args. Если длина массива 1, то это не массив, а единичный объект?
0
880 / 559 / 291
Регистрация: 21.11.2012
Сообщений: 1,554
30.04.2019, 11:22
wrq2017,

ну дык и создайте конструктор, который принимает массив, т.о. отпадут дальнейшие вопросы)

C#
1
2
3
public SomeEditForm2(SomeType2[] arr)
{
}
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 11:27  [ТС]
Цитата Сообщение от hamin Посмотреть сообщение
ну дык и создайте конструктор, который принимает массив, т.о. отпадут дальнейшие вопросы)
Да, в самом начале я и написал, что в качестве решения вопроса вижу этот способ, но он мне не очень нравится, т.к. объекты разного типа будут в массиве и я не знаю - какого размера массив будет передан в конструктор, необходимо проверять будет проверять его на длину и соблюдать порядок передачи параметров в массиве.

Добавлено через 2 минуты
А я хотел бы, чтобы параметры, которые не были переданы в массиве объектов, получили значение по умолчанию - null
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 11:32
Цитата Сообщение от wrq2017 Посмотреть сообщение
Соль видимо в params object [] args. Если длина массива 1, то это не массив, а единичный объект?
Да - в том смысле что принимает массив из-за такого объявления.
Но нет - что это причина ошибки
Миниатюры
Переменное количество параметров для типовой формы редактирования  
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 11:39
Лучший ответ Сообщение было отмечено wrq2017 как решение

Решение

Цитата Сообщение от wrq2017 Посмотреть сообщение
А я хотел бы, чтобы параметры, которые не были переданы в массиве объектов, получили значение по умолчанию - null
Я же показал Вам один из способов решения.

Вот ещё - более простой вариант
C#
1
2
3
4
5
6
        public SomeEditForm2(params object[] objs)
        {
            Obj2 = objs.OfType<SomeType2>().FirstOrDefault();
            Obj3 = objs.OfType<SomeType3>().FirstOrDefault ();
            Obj4 = objs.OfType<SomeType4>().FirstOrDefault();
        }
Миниатюры
Переменное количество параметров для типовой формы редактирования  
1
 Аватар для Kazbek17
1484 / 939 / 454
Регистрация: 06.02.2012
Сообщений: 2,868
30.04.2019, 11:55
Цитата Сообщение от wrq2017 Посмотреть сообщение
Да, в самом начале я и написал, что в качестве решения вопроса вижу этот способ, но он мне не очень нравится, т.к. объекты разного типа будут в массиве и я не знаю - какого размера массив будет передан в конструктор, необходимо проверять будет проверять его на длину и соблюдать порядок передачи параметров в массиве.
2 раза перечитал так и не понял что вы хотите сделать. Если вы не знаете какое кол-во и какой тип будет передаваться в конструктор, то для этих целей, как говорилось выше params object[] args. Если известно размер массива object[] args. Оба типа работают по одному принципу, но передача аргументов происходит в таком порядке.

params object[] args
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Перед вызовом вы создаете переменные и присваиваете им значение.
object obj1;
object obj2;
object obj3;
//И.т.д
 
//Вызываете  и передаете аргументы
SomeEditForm2(obj1,obj2,obj3);
 
 
public SomeEditForm2(params [] object args)
{
  //Проходим по циклу и дергаем кол-во переданных аргументов.
   for(int i = 0; i < args.Length; i++)
   {
       SomeType2 result = (Нужно приведение к типу)args[i];
       result.Тра-ля-ля
       //И.т.д
   }
}
params [] SomeType1
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Перед вызовом вы создаете переменные и присваиваете им значение.
SomeType1 obj1;
SomeType1 obj2;
SomeType1 obj3;
//И.т.д
 
//Вызываете  и передаете аргументы
SomeEditForm2(obj1,obj2,obj3);
 
 
public SomeEditForm2(params [] SomeType1 args)
{
  //Проходим по циклу и дергаем кол-во переданных аргументов.
   for(int i = 0; i < args.Length; i++)
   {
       SomeType2 result = args[i];
       result.Тра-ля-ля
       //И.т.д
   }
}
[] SomeType1
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Перед вызовом вы передаете так.
SomeType1 obj1;
SomeType1 obj2;
SomeType1 obj3;
//И.т.д
 
//Создаем массив.
SomeType1 [] obj = new SomeType1 []{obj1,obj2,obj3};
 
//Вызываете  и передаете аргументы
SomeEditForm2(obj1);
 
 
public SomeEditForm2(SomeType1 [] args)
{
  //Проходим по циклу и дергаем кол-во переданных аргументов.
   for(int i = 0; i < args.Length; i++)
   {
       SomeType2 result = args[i];
       result.Тра-ля-ля
       //И.т.д
   }
}
У меня есть подозрение, что автор хочет сделать универсальную форму редактирование, для разных видов услуг-товаров.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16124 / 11248 / 2888
Регистрация: 21.04.2018
Сообщений: 33,082
Записей в блоге: 2
30.04.2019, 12:23
Цитата Сообщение от Kazbek17 Посмотреть сообщение
У меня есть подозрение, что автор хочет сделать универсальную форму редактирование, для разных видов услуг-товаров.
Мои подозрения - иссякли...
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 13:53  [ТС]
За автора не надо подозревать, автор сам может рассказать. Есть некоторое количество разных сущностей. Каждая сущность редактируется в своей уникальной форме. Но метод вызова этих форм универсиализирован.
Всё работало хорошо
Но в некоторый момент в некоторой форме возникла необходимость передачи не только самого объекта, но и дополнительных параметров. В связи с чем и возник вопрос.

Добавлено через 2 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вот ещё - более простой вариант
C#Выделить код
1
2
3
4
5
6
* * * * public SomeEditForm2(params object[] objs)
* * * * {
* * * * * * Obj2 = objs.OfType<SomeType2>().FirstOrDefault( );
* * * * * * Obj3 = objs.OfType<SomeType3>().FirstOrDefault ();
* * * * * * Obj4 = objs.OfType<SomeType4>().FirstOrDefault( );
* * * * }
Ок. Этот вариант мне нравится больше всего. Спасибо!
0
 Аватар для Kazbek17
1484 / 939 / 454
Регистрация: 06.02.2012
Сообщений: 2,868
30.04.2019, 14:25
Цитата Сообщение от wrq2017 Посмотреть сообщение
Ок. Этот вариант мне нравится больше всего. Спасибо!
Но этот вариант не универсальный. От него толку очень мало.
1
3 / 3 / 2
Регистрация: 30.07.2017
Сообщений: 223
30.04.2019, 14:27  [ТС]
Цитата Сообщение от Kazbek17 Посмотреть сообщение
Но этот вариант не универсальный. От него толку очень мало.
Почему?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.04.2019, 14:27
Помогаю со студенческими работами здесь

Переменное число параметров
Здравствуйте, начал изучать Python, как прошла неделя уже), скачал книгу &quot;Укус питона&quot;, очень доходчивая книжка, но вот не до конца...

Переменное число параметров шаблона
Здоровеньки булы. Не уверен, что название темы точно отражает суть вопроса. Есть заготовка шаблонного делегата, параметры которого -...

QStringList в переменное число параметров
Прошу показать как объявить метод с переменным числом параметров типа QStringList, и как перемещаться по этим параметрам?

Как задать переменное количество аргументов для чужой функции?
Помогите пожалуйста, имеется куча шаблонного кода когда выполняешь ExecSQLEx, например: if not...

Как передать в функцию переменное число параметров
Приветствую... вопрос есть положим есть функция: UART0printf(const char *fmt, ...) которая формирует строку и выводит ее в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru