Есть ли поддержка в языке работы с разными типами в 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");
}
}
т.е. нужна сериализация в зависимости от типа своя. Или вариант строить такие конструкции с динамическим определением типа?
Здравствуйте, 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. А готовые библиотеки сериализации чем не подходят?
Здравствуйте, 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>, который содержит в себе список типов и их сериализаторов.
Здравствуйте, 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 = …