silverlight TypeDescriptor.GetConverter заменитель - PullRequest
11 голосов
/ 03 июня 2010

Я пытаюсь использовать проект LINQ to CSV в silverlight (это отличный проект), потому что он с открытым исходным кодом, я подумал, что могу просто перекомпилировать в качестве библиотеки классов silverlight, но, к сожалению, похоже, что он использует функция недоступна в Silverlight. Метод TypeDescriptor.GetConverter .

Используется для поиска преобразователей типов, чтобы правильно проанализировать столбцы csv и соответствующие им типы CLR. У меня нет проблем с внесением изменений в исходные коды linqtocsv, чтобы он работал в Silverlight, но я просто не знаю, что будет эквивалентной операцией в silverlight. Различные поиски в Google привели меня на эту страницу , но все, что говорит о том, что синтаксический анализатор XAML имеет способ сделать это (но он не говорит, как получить доступ к этой функции).

В двух словах, вопрос:

как мне воспроизвести функциональность TypeDescriptor.GetConverter?

Мне не обязательно нужно точное снижение замены, я просто хочу знать хороший способ сделать это без жесткого кодирования связки типа <---> преобразователей типов.

Ответы [ 4 ]

8 голосов
/ 12 июня 2010

На легких каркасах у вас ограниченные возможности; Я бы не стал уклоняться от небольшого жесткого кодирования, особенно если вам нужно только поддерживать основные типы. Это также будет проще и быстрее, чем полная опция TypeConverter. Что-то вроде:

    static object Parse(Type type, string s)
    {
        switch (Type.GetTypeCode(type))
        {
            case TypeCode.Boolean: return bool.Parse(s);
            case TypeCode.Byte: return byte.Parse(s);
            case TypeCode.Char: return s[0];
            case TypeCode.DateTime: return DateTime.Parse(s);
                ...
        }
    }
1 голос
/ 28 октября 2010

Я создал довольно полный набор инструментов для решения этой проблемы. Есть много шагов, но вот оно:

1) Возвращает исходное значение, если целевой тип назначается из исходного значения. 2) В противном случае создайте преобразователь типов (здесь будут интересные части)

public static TypeConverter GetTypeConverter(Type type) 
{
   TypeConverterAttribute attribute = (TypeConverterAttribute)Attribute.GetCustomAttribute(type, typeof(TypeConverterAttribute), false);
   if (attribute != null)
   {
     try 
     {
       var converterType = Type.GetType(attribute.ConverterTypeName, false);
       if (converterType != null) 
       {
         return (Activator.CreateInstance(converterType) as TypeConverter);
 }
     }
     catch {}
   }
   return new XamlStringConverter(type);
  }

Ничего удивительного здесь. Но обратите внимание, что XamlStringConverter возвращается, если конвертер не найден. Он использует Xaml Parser для конвертации вещей. Поле типа включено в конвертер и содержит тип, переданный конструктору.

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
        var strValue = value as string;
        if (strValue != null) {
            if (this.type == typeof(bool)) {
                return bool.Parse(strValue);
            }
            if (this.type.IsEnum) {
                return Enum.Parse(this.type, stringValue, false);
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("<ContentControl xmlns='http://schemas.microsoft.com/client/2007' xmlns:c='" + ("clr-namespace:" + this.type.Namespace + ";assembly=" + this.type.Assembly.FullName.Split(new char[] { ',' })[0]) + "'>\n");
            stringBuilder.Append("<c:" + this.type.Name + ">\n");
            stringBuilder.Append(strValue);
            stringBuilder.Append("</c:" + this.type.Name + ">\n");
            stringBuilder.Append("</ContentControl>");
            ContentControl instance = XamlReader.Load(stringBuilder.ToString()) as ContentControl;
            if (instance != null) {
                return instance.Content;
            }
        }
        return base.ConvertFrom(context, culture, value);
    }
0 голосов
/ 29 мая 2012

От: http://lostechies.com/jimmybogard/2010/02/19/automapper-for-silverlight-3-0-alpha/

private static TypeConverter GetTypeConverter(Type type)
{
    var attributes = type.GetCustomAttributes(typeof(TypeConverterAttribute), false);

    if (attributes.Length != 1)
        return new TypeConverter();

    var converterAttribute = (TypeConverterAttribute)attributes[0];
    var converterType = Type.GetType(converterAttribute.ConverterTypeName);

    if (converterType == null)
        return new TypeConverter();

    return Activator.CreateInstance(converterType) as TypeConverter;
}
0 голосов
/ 21 февраля 2012

Если вы уверены, что можете положиться на последовательность, используйте это:

private static object DeserializeValue(string value, Type type)
{
  //uncomment if used with XML
  //value = HttpUtility.HtmlDecode(value);
  switch (Type.GetTypeCode(type))
  {
    case TypeCode.Empty:
      return null;
    case TypeCode.DBNull:
      return DBNull.Value;
    case TypeCode.Object:
      throw new InvalidCastException(
        string.Format("The type '{0}' is not supported.", type));
    case TypeCode.String:
      return value;
    default:
      {
        var convertible = value as IConvertible;
        return convertible.ToType(type, CultureInfo.InvariantCulture);
      }
  }
}

Убедитесь, что ваша функция сериализации соответствует культуре десериализации для согласованности:

private static string SerializeValue(object value)
{
  if (!(value is IConvertible))
    throw new InvalidCastException(
      string.Format("The type '{0}' is not supported.", value.GetType()));
  var convertible = (IConvertible)value;
  var str = convertible.ToString(CultureInfo.InvariantCulture);
  //uncomment if you're serializing to XML
  //return HttpUtility.HtmlEncode(str);
  return str;
}

Обратите внимание, что поддерживаются только примитивные типы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...