일반 유형 변환 FROM 문자열


234

다른 클래스의 "속성"을 저장하는 데 사용하려는 클래스가 있습니다. 이러한 속성에는 단순히 이름과 값이 있습니다. 이상적으로 는 내가 원하는 것은 유형이 지정된 속성 을 추가 하여 반환 된 "값"이 항상 원하는 유형이되도록하는 것입니다.

유형은 항상 기본 형식이어야합니다. 이 클래스는 기본적으로 이름과 값을 문자열로 저장하는 추상 클래스를 서브 클래스합니다. 이 서브 클래스는 기본 클래스에 유형 안전성을 추가 할뿐만 아니라 변환을 절약 할 수 있다는 아이디어입니다.

그래서 나는 (거의)이 클래스를 만들었습니다.

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

따라서 질문은 다음과 같습니다.

문자열에서 기본으로 다시 변환하는 "일반적인"방법이 있습니까?

보드 전체에서 변환을 연결하는 일반적인 인터페이스를 찾을 수없는 것 같습니다 ( ITryParsable 과 같은 것이 이상적 이었습니다 ).


구체적인 클래스의 예를 보거나 스 니펫을 보려는 것에 관심이 있습니다. :)
Jon Limjap

기본 수업의 관련 부분을 게시 할 수 있습니까?
JJS

사람이 닷넷 표준 1.2에서 작업 여기에 답변을 얻을 수 있는지 궁금 : /
댄 Rayson

답변:


374

나는 당신의 의도를 올바르게 이해했는지 확실하지 않지만 이것이 도움이되는지 봅시다.

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

스트림을 일반 유형으로 직렬화 해제하는 방법에 대해 며칠 동안 궁금했습니다. 감사합니다 :)
Trap

3
하지만 나는 동의 Convert.ChangeType매우 보편적이고 확장 가능한 솔루션이 아닙니다은 가장 기본적인 유형에 대해 작동합니다. 더 나은 것이 필요하다면,이 방법을 Tim이 제안한 것보다 큰 것으로 랩핑하거나 다른 변환 방법을 사용하는 것은 문제가되지 않습니다.
lubos hasko

18
IConvertible : 나는 확실히 곳의 T를 추가
MikeT

5
T는 IConvertible이 아니고 Type of base.Value 여야합니다.
chapluck

74

lubos hasko의 메소드는 널 입력 가능에 실패합니다. 아래 방법은 nullable에 적용됩니다. 그래도 나는 그것을 찾지 못했습니다. Google을 통해 찾았습니다. http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx "Tuna Toksoz"에 대한 크레딧

먼저 사용법 :

TConverter.ChangeType<T>(StringValue);  

수업은 아래와 같습니다.

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

열거 형 및 기타 복잡한 구조에 대한 대체 변환 옵션을 추가하지만 호가 좋습니다.
Tomer W

2
왜 RegisterTypeConverter인가? 손으로 변환기를 등록해야합니까? (불행히도 링크가 죽었으므로 읽을 수 없었습니다)
Cohen

여러 번의 전환에 대해서는 tc( TypeConverter)을 한 번만 만들어야 합니다. TypeConverter리플렉션을 사용하여을 검색하기 때문에 속도가 느립니다 TypeConverterAttribute. 단일 개인 TypeConverter필드 를 초기화 하면 TypeConverter여러 번 재사용 할 수 있습니다 .
Kevin P. Rice

잘 작동하지만 T가 인 경우 object예외가 발생합니다. `if (typeof (T) .IsPrimitive) {return TConverter.ChangeType <T> (StringValue);를 사용하여 해결할 수있었습니다. } else {object o = (object) StringValue; 로 돌아가; }`사용 샘플의 대체물 TConverter.ChangeType<T>(StringValue)
Matt

14

많은 유형 (정수, double, DateTime 등)에는 정적 구문 분석 방법이 있습니다. 리플렉션을 사용하여 호출 할 수 있습니다.

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

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

8
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)

TypeDescriptor는 객체 GetConvertor를 받아들이는 메소드 를 가진 클래스 이며, 지정된 객체를 위해 메소드를 Type호출 ConvertFrom하여 변환 할 수 있습니다 value.


개인적 으로이 클래스는 모든 클래스에서 IConvertible 인터페이스를 구현해야하기 때문에 Convert.ChangeType 메서드 대신 변환을 처리하는 것이 더 좋습니다.
Sauleil

3

traits 클래스 와 같은 구문을 사용할 수 있습니다 . 이런 식으로, 문자열을 자체 유형의 값으로 변환하는 방법을 알고있는 매개 변수화 된 헬퍼 클래스가 있습니다. 그러면 getter가 다음과 같이 보일 수 있습니다.

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

이제 매개 변수화 된 형식에 대한 내 경험은 C ++ 및 해당 템플릿으로 제한되지만 C # 제네릭을 사용하여 같은 종류의 작업을 수행 할 수있는 방법이 있다고 생각합니다.


C #에는 일반 버전이 없습니다.
시미 바이 츠 핸들러

3

정전기를 확인하십시오 Nullable.GetUnderlyingType. -기본 유형이 null 인 경우 템플릿 매개 변수가 아니고 Nullable해당 유형을 직접 사용할 수 있습니다. 기본 유형이 null이 아닌 경우 기본 유형을 변환에 사용합니다.

나를 위해 일하는 것 같습니다 :

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

1

Bob 의 답변 에서 영감을 얻은 이러한 확장은 null 값 변환과 모든 기본 변환을 앞뒤로 지원합니다.

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

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

            int? intValue = null;
            var strResult = intValue.Convert<string>();

0
public class TypedProperty<T> : Property
{
    public T TypedValue
    {
        get { return (T)(object)base.Value; }
        set { base.Value = value.ToString();}
    }
}

객체를 통한 변환을 사용합니다. 조금 더 간단합니다.


덕분에 인터페이스에서 T를 변환해야하며 간단한 변환 T 개체가 정확하고 쉽고 빠르며 작동합니다.
LXG

5
(int) (객체) "54"; 치명적입니다! 이것은 VB가 아닙니다!
Tomer W

0

나는 lobos answer를 사용했으며 작동합니다. 그러나 문화 설정으로 인해 복식 변환에 문제가있었습니다 . 그래서 나는 추가했다

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

0

또 다른 변형. 문자열이 null이고 T가 nullable 이 아닌 상황과 Nullable을 처리 합니다.

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

0

아래와 같이 한 줄로 할 수 있습니다.

YourClass obj = (YourClass)Convert.ChangeType(YourValue, typeof(YourClass));

행복한 코딩;)


답변으로 코드를 공유 할 때 설명해보십시오.
Yunus Temurlenk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.