Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.06.2019, 11:56   #1
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию Обобщение. Инициализация экземпляра наследуемого класса

Уважаемые форумчане, подскажите пожалуйста, как решить такой вопрос:
Есть абстрактный обобщенный класс A<T>. У него есть наследники, скажем B<double>, C<double> и D<Complex>. Из tsv файла я выгружаю значения в словарь. Так вот, есть ли способ адекватно проинициализировать эти значения для разных наследуемых классов? Мне в голову пришла только такая мысль:
Код:
abstract class A<T>
{
   protected T value;
   protected A() {}
   protected A(T val)
   {
      value = val;
   }
   public abstract void SetValue(string src);
}
class B<double>
{
   public B(double val) : base (val) {}
   public override void SetValue(string src)
   {
      value = Convert.ToDouble(src);
   }
}
class C<double>
...
class D<Complex>
{
   public D(Complex val) : base (val) {}
   public override void SetValue(string src)
   {
      string[] temp = src.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
      value.Re = Convert.ToDouble(temp[0]);
      value.Im = Convert.ToDouble(temp[1]);
   }
}

static class Program
{
   static void Main()
   {
      Dictionary<B,C> dic = GetValues<C>();
      Dictionary<B,D> dic = GetValues<D>();
   }
   
   static Dictionary<B,T> GetValues<T>()
   {
      Dictionary<B,T> res = new Dictionary<B,T>();
      string[] strs = File.ReadAllLines("test.txt");
      foreach (string str in strs)
      {
         string[] temp = str.Split(new char[] {'\t'}, StringSplitOptions.RemoveEmptyEntries);
         B b = new B(temp[0]);
         T t = new T();
         T.SetValue(temp[1]);
         res.Add(b,t);
      }
      return res;
   }
}
В данном подходе не нравится, что надо создавать объект с нужным значением в 2 подхода (создание объекта с помощью стандартного конструктора и устанавливать значение с помощью SetValue()). Возможен ли иной вариант решения данного вопроса?
Заранее спасибо

Последний раз редактировалось max_prorok; 21.06.2019 в 12:15.
max_prorok вне форума Ответить с цитированием
Старый 21.06.2019, 13:17   #2
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

А сделать конструктор который принимает string не судьба?
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 21.06.2019, 14:01   #3
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Цитата:
Сообщение от WorldMaster Посмотреть сообщение
А сделать конструктор который принимает string не судьба?
А он будет работать?
Мне вот например стидия выдает ошибку: 'T": при создании экземпляра типа переменной не удается задать аргументы на строке
Код:
T t = new T(temp[1]);
Что в принципе и логично, сделать абстрактный конструктор нельзя, и в ограничениях на Т можно поставить только наличие стандартного конструктора. Откуда знать, есть ли у класса, который подставляется под Т наличие конструктора со стрингом на входе?
Если я неправильно понял вашу мысль, не могли бы привести пример такой реализации?

Последний раз редактировалось max_prorok; 21.06.2019 в 14:03.
max_prorok вне форума Ответить с цитированием
Старый 21.06.2019, 14:07   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Код:
using System;

abstract class A<T>
{
   protected T value;
   protected A() {}
   protected A(T val)
   {
      value = val;
   }
}
class B : A<double>
{
   public B(double val, string src) : base (val) {
      value = Convert.ToDouble(src);
   }
}

public class Test
{
	public static void Main()
	{
		B a = new B(12.4, "10");
	}
}
p51x вне форума Ответить с цитированием
Старый 21.06.2019, 14:17   #5
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
B a = new B(12.4, "10");
В вашем примере Вы явно указываете тип переменной, а в моем случае - тип обобщенный.
max_prorok вне форума Ответить с цитированием
Старый 21.06.2019, 14:38   #6
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

Код:
class B: A<double>
    {
        public B(double val) : base(val) { }
        public B(string val) : base()
        {
            SetValue(val);
        }
        public override void SetValue(string src)
        {
            value = Convert.ToDouble(src);
        }
    }
Так то что мешает сделать?
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 21.06.2019, 14:44   #7
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Цитата:
Сообщение от WorldMaster Посмотреть сообщение
Так то что мешает сделать?
Не могу я вызвать конструктор B(string val) для обобщенного типа Т в методе GetValues() с помощью
Код:
T t = new T(temp[1]);
max_prorok вне форума Ответить с цитированием
Старый 21.06.2019, 14:46   #8
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

Цитата:
Сообщение от max_prorok Посмотреть сообщение
Не могу я вызвать конструктор B(string val) для обобщенного типа Т в методе GetValues() с помощью
Код:
T t = new T(temp[1]);
Так при чем тут обобщенный тип? У вас все классы имеют разный тип. И преобразование из строки тоже.
Значит пропишите в абстрактном классе метод преобразования типов.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 21.06.2019, 14:53   #9
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Цитата:
Сообщение от max_prorok Посмотреть сообщение
для обобщенного типа Т
С каких T стал обобщенным? Вы по-моему вообще не понимаете ни наследование, ни обобщеность.
p51x вне форума Ответить с цитированием
Старый 21.06.2019, 15:26   #10
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
С каких T стал обобщенным? Вы по-моему вообще не понимаете ни наследование, ни обобщеность.
Прошу прощения, неверно изложил мысль. Имелось в виду, что в обобщенном методе GetValues<T>() я не могу вызвать никакой другой конструктор для типа Т кроме как стандартный.
max_prorok вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание экземпляра подходящего класса GrandmaSquid3 Общие вопросы C/C++ 0 08.12.2018 18:23
Вызов конструктора производного класса для экземпляра базового класса max_prorok Помощь студентам 5 09.09.2015 09:39
Создание экземпляра класса biohazard120 Общие вопросы Delphi 11 15.09.2012 13:23
Освобождение памяти от экземпляра класса Mixim Общие вопросы .NET 8 05.01.2011 17:27
удаление экземпляра класса Juffin Общие вопросы Delphi 5 02.11.2010 11:57