Generic
От: Didi  
Дата: 13.01.16 18:50
Оценка:
Есть ли поддержка в языке работы с разными типами в generic
например:
class A<T>
{
T value;
public A(T t){value = t;}
// каждый тип нужно сериализовать по своему
public String MyToString()
{
if( value is String) return value as String;
else if( value is DateTime) return  System.XML.Convert.ToString((DateTime)(Object) value);
else throw new Exception("unknown type");
}
}

т.е. нужна сериализация в зависимости от типа своя. Или вариант строить такие конструкции с динамическим определением типа?
Re: Generic
От: Sinix  
Дата: 13.01.16 19:40
Оценка: +1
Здравствуйте, Didi, Вы писали:

D>т.е. нужна сериализация в зависимости от типа своя. Или вариант строить такие конструкции с динамическим определением типа?


Текущий вариант будет работать. Если типов много и писать однотипный код не хочется, можно поискать приключений с dynamic.

Почему приключений? А попробуйте угадать вывод вот тут:
        private class A<T>
        {
            private T value;
            public A(T t)
            {
                value = t;
            }
            // каждый тип нужно сериализовать по своему
            public String MyToString()
            {
                return (string)Serialise((dynamic)value);
            }

            private string Serialise(string value)
            {
                return "string";
            }
            private string Serialise(DateTime value)
            {
                return "DateTime";
            }
            private string Serialise(int value)
            {
                return "int";
            }
            private string Serialise(object value)
            {
                return "obj";
            }
        }
        private static void Main()
        {
            try
            {
                Console.WriteLine(new A<int>(23).MyToString());
                Console.WriteLine(new A<byte>(23).MyToString());
                Console.WriteLine(new A<byte?>(23).MyToString());
                Console.WriteLine(new A<long>(23).MyToString());
                Console.WriteLine(new A<int[]>(new[] { 0 }).MyToString());
                Console.WriteLine(new A<string>(null).MyToString());
                Console.WriteLine(new A<Stream>(null).MyToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("Done.");
            Console.ReadKey();
        }


Не подходит — или ждать паттерн-матчинга в c#7, или сделать аналог dynamic, только с более строгим биндингом — словарь <Type,Func<object, string>>, пишется за 5 минут.

P.S. А готовые библиотеки сериализации чем не подходят?
Re: Generic
От: Spinifex Россия https://architecture-cleaning.ru/
Дата: 13.01.16 19:55
Оценка: +1
Здравствуйте, Didi, Вы писали:

D>Есть ли поддержка в языке работы с разными типами в generic

D>например:
D>
D>class A<T>
D>{
D>T value;
D>public A(T t){value = t;}
D>// каждый тип нужно сериализовать по своему
D>public String MyToString()
D>{
D>if( value is String) return value as String;
D>else if( value is DateTime) return  System.XML.Convert.ToString((DateTime)(Object) value);
D>else throw new Exception("unknown type");
D>}
D>}
D>

D>т.е. нужна сериализация в зависимости от типа своя. Или вариант строить такие конструкции с динамическим определением типа?
Что-то не вижу как это можно сделать через generic. Все таки метод MyToString не является generic (помним про перевод с английского — общий), раз приходится переопределять его логику для разных типов. Здесь лучше сделать redesign небольшой. Т.е. либо у вас сам объект будет уметь себя сериализовывать — логично, ведь может быть какое-то внутреннее состояние, которое не хочется вытаскивать наружу. Либо вместо if у вас будет Dictionary<Type, Serializer>, который содержит в себе список типов и их сериализаторов.
Re: Generic
От: xy012111  
Дата: 14.01.16 09:03
Оценка:
Здравствуйте, Didi, Вы писали:

D>Есть ли поддержка в языке работы с разными типами в generic

D>т.е. нужна сериализация в зависимости от типа своя. Или вариант строить такие конструкции с динамическим определением типа?

Если речь о таких вот базовых типах, то достаточно завести словарик:
private static readonly IReadOnlyDictionary<Type, Func<object, string>> ToStringMethods = new Dictionary<Type, Func<object, string>>()
{
    { typeof(string), value => (string)value },
    { typeof(DateTime), value => XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Unspecified) },

    // …
};

и тогда
public string ToString() {
  if(value == null) {
    return String.Empty;
  }

  Func<object, string> convert;
  if(!ToStringMethods.TryGetValue(value.GetType(), out convert)) {
    throw new Exception("unknown type");
  }

  return convert(value);
}


Можно немного допилить, если ToStringMethods добавить в класс, где уже объявлен дженерик-тип и могут быть дополнительные какие констрейнты:
private static readonly IReadOnlyDictionary<Type, Func<T, string>> ToStringMethods = …
Отредактировано 14.01.2016 9:05 xy012111 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.