Pergunta

Eu tenho uma classe que pretende utilizar para armazenar "propriedades" para outra classe.Estas propriedades simplesmente ter um nome e um valor.Idealmente, o que eu gostaria é que para ser capaz de adicionar escreveu propriedades, de tal forma que o "valor" retornado é sempre do tipo que eu quero ser.

O tipo deve ser sempre um primitivo.Esta classe subclasses de uma classe abstrata que basicamente armazena o nome e o valor de cadeia de caracteres.A idéia de que esta subclasse irá adicionar algum tipo de segurança para a classe base (bem como de verão-me sobre alguns de conversão).

Então, eu criei uma classe que é (aproximadamente) este:

public class TypedProperty<DataType> : Property
{
    public DataType TypedValue
    {
        get { // Having problems here! }
        set { base.Value = value.ToString();}
    }
}

Então a pergunta é:

Existe um "genérico" para converter de string de volta para um primitivo?

Eu não consigo encontrar qualquer interface genérica que liga a conversão através da placa (algo como ITryParsable teria sido o ideal!).

Foi útil?

Solução

Eu não tenho certeza se eu entendi suas intenções corretamente, mas vamos ver se isso ajuda.

public class TypedProperty<T> : Property where T : IConvertible
{
    public T TypedValue
    {
        get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
        set { base.Value = value.ToString();}
    }
}

Outras dicas

lubos hasko da falha de método para nullables.O método abaixo vai trabalhar para nullables.Eu não venha com ele, embora.Eu achei via Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Crédito para a Tuna Toksoz"

O uso de primeira:

TConverter.ChangeType<T>(StringValue);  

A classe abaixo.

public static class TConverter
{
    public static T ChangeType<T>(object value)
    {
        return (T)ChangeType(typeof(T), value);
    }

    public static object ChangeType(Type t, object value)
    {
        TypeConverter tc = TypeDescriptor.GetConverter(t);
        return tc.ConvertFrom(value);
    }

    public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
    {

        TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
    }
}

Para muitos tipos (integer, double, DateTime, etc), existe um método de análise estático.Você pode invocá-lo usando a reflexão:

MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );

if (m != null)
{
    return m.Invoke(null, new object[] { base.Value });
}
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)

TypeDescriptor é a classe ter método GetConvertor que aceitar um Type objeto e, em seguida, você pode chamar ConvertFrom método para converter o value para que o objeto especificado.

Você poderia usar uma construção, como um características de classe.Desta forma, você teria um parametrizado, auxiliar de classe que sabe como converter uma string para um valor de seu próprio tipo.Em seguida, o getter pode ter este aspecto:

get { return StringConverter<DataType>.FromString(base.Value); }

Agora, devo ressaltar que a minha experiência com tipos parametrizados é limitado para C++ e seus modelos, mas eu imagino que existe alguma forma de fazer a mesma coisa usando C# genéricos.

Verificação estática Nullable.GetUnderlyingType.- Se o tipo subjacente é nulo, então o parâmetro de modelo não é Nullable, e nós podemos usar o tipo diretamente - Se o tipo subjacente não é nulo, em seguida, utilize o tipo subjacente na conversão.

Parece funcionar para mim:

public object Get( string _toparse, Type _t )
{
    // Test for Nullable<T> and return the base type instead:
    Type undertype = Nullable.GetUnderlyingType(_t);
    Type basetype = undertype == null ? _t : undertype;
    return Convert.ChangeType(_toparse, basetype);
}

public T Get<T>(string _key)
{
    return (T)Get(_key, typeof(T));
}

public void test()
{
    int x = Get<int>("14");
    int? nx = Get<Nullable<int>>("14");
}
public class TypedProperty<T> : Property
{
    public T TypedValue
    {
        get { return (T)(object)base.Value; }
        set { base.Value = value.ToString();}
    }
}

Eu usando a conversão através de um objeto.Ele é um pouco mais simples.

Eu usei lobos resposta e ele funciona.Mas eu tinha um problema com a conversão de dobra devido a configurações de cultura.Então eu adicionei

return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);

Ainda outra variação.Alças Nullables, bem como situações em que a cadeia é nulo e T é não anulável.

public class TypedProperty<T> : Property where T : IConvertible
{
    public T TypedValue
    {
        get
        {
            if (base.Value == null) return default(T);
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
            return (T)Convert.ChangeType(base.Value, type);
        }
        set { base.Value = value.ToString(); }
    }
}

Com a inspiração do Bob's respostas, estas extensões também suporta o valor nulo de conversão e todas as primitivas de conversão de volta e o quarto.

public static class ConversionExtensions
{
        public static object Convert(this object value, Type t)
        {
            Type underlyingType = Nullable.GetUnderlyingType(t);

            if (underlyingType != null && value == null)
            {
                return null;
            }
            Type basetype = underlyingType == null ? t : underlyingType;
            return System.Convert.ChangeType(value, basetype);
        }

        public static T Convert<T>(this object value)
        {
            return (T)value.Convert(typeof(T));
        }
}

Exemplos

            string stringValue = null;
            int? intResult = stringValue.Convert<int?>();

            int? intValue = null;
            var strResult = intValue.Convert<string>();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top