C # динамические преобразования типов - PullRequest
6 голосов
/ 15 марта 2009

У нас есть 2 объекта A & B: A - это system.string, а B - некоторый примитивный тип .net (string, int и т. Д.). мы хотим написать общий код для назначения преобразованного (проанализированного) значения B в A. Есть предложения? Спасибо, Ади Барда

Ответы [ 4 ]

20 голосов
/ 15 марта 2009

Наиболее прагматичным и универсальным способом преобразования строк является TypeConverter:

public static T Parse<T>(string value)
{
    // or ConvertFromInvariantString if you are doing serialization
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
}

В преобразователях типов больше типов, чем в IConvertible и т. Д., И вы также можете добавлять преобразователи в новые типы - оба во время компиляции;

[TypeConverter(typeof(MyCustomConverter))]
class Foo {...}

class MyCustomConverter : TypeConverter {
     // override ConvertFrom/ConvertTo 
}

, а также во время выполнения, если вам нужно (для типов, которые вам не принадлежат):

TypeDescriptor.AddAttributes(typeof(Bar),
    new TypeConverterAttribute(typeof(MyCustomConverter)));
5 голосов
/ 15 марта 2009

Как уже упоминалось, System.Convert и IConvertible были бы первой ставкой. Если по какой-либо причине вы не можете использовать их (например, если системные преобразования по умолчанию для встроенных типов вам не подходят), один из подходов состоит в том, чтобы создать словарь, содержащий делегаты для каждого преобразования, и выполнить поиск в нем при необходимости найдите правильное преобразование.

Например; если вы хотите преобразовать строку в тип X, вы можете получить следующее:

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(SimpleConvert.To<double>("5.6"));
        Console.WriteLine(SimpleConvert.To<decimal>("42"));
    }
}

public static class SimpleConvert
{
    public static T To<T>(string value)
    {
        Type target = typeof (T);
        if (dicConversions.ContainsKey(target))
            return (T) dicConversions[target](value);

        throw new NotSupportedException("The specified type is not supported");
    }

    private static readonly Dictionary<Type, Func<string, object>> dicConversions = new Dictionary <Type, Func<string, object>> {
        { typeof (Decimal), v => Convert.ToDecimal(v) },
        { typeof (double), v => Convert.ToDouble( v) } };
}

Очевидно, вы, возможно, захотите сделать что-то более интересное в своих пользовательских процедурах преобразования, но это демонстрирует суть.

3 голосов
/ 15 марта 2009

Что не так с уже существующим System.Convert классом и IConvertible интерфейсом?

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