2009-03-15 19 views
6

Abbiamo 2 oggetti A & B: A è system.string e B è un tipo .net primitivo (stringa, int ecc.). vogliamo scrivere codice generico per assegnare il valore convertito (analizzato) di B in A. Qualche suggerimento? Grazie, Adi BardaConversioni di tipo dinamico C#

risposta

20

Il modo più pragmatico e versatile per fare conversioni di stringhe è con TypeConverter:

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

Altri tipi hanno tipo convertitori di implementare IConvertible ecc, ed è anche possibile aggiungere convertitori a nuovi tipi - sia a livello di compilazione tempo;

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

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

e anche in fase di esecuzione se è necessario (per i tipi non si possiede):

TypeDescriptor.AddAttributes(typeof(Bar), 
    new TypeConverterAttribute(typeof(MyCustomConverter))); 
3

Cosa c'è di sbagliato con il già esistente System.Convert classe e l'interfaccia IConvertible?

+4

In particolare, Convert.ChangeType potrebbe essere quello che stai cercando. – Noldorin

5

Come già accennato, System.Convert e IConvertible sarebbero la prima scommessa. Se per qualche motivo non è possibile utilizzarli (ad esempio, se le conversioni di sistema predefinite per i tipi incorporati non sono adeguati per te), un approccio consiste nel creare un dizionario che contenga i delegati per ogni conversione e fare una ricerca in questo per trova la conversione corretta quando necessario.

Ad esempio; quando si desidera convertire da stringa a digitare X si potrebbe avere la seguente:

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) } }; 
} 

Ovviamente, si sarebbe probabilmente vuole fare qualcosa di più interessante nella vostra routine di conversione personalizzato, ma dimostra il punto.

+0

+1: approccio interessante per estendere l'IConvertible ai tipi non convertibili. –