2008-08-12 151 views
186

我有一個類,我想用來存儲另一個類的「屬性」。這些屬性只有一個名稱和一個值。理想情況下,我希望能夠添加鍵入的屬性,以便返回的「值」始終是我希望的類型。通用類型轉換從字符串

該類型應該始終是原始類型。這個類繼承了一個抽象類,它基本上將字符串的名稱和值存儲起來。這個想法是,這個子類將爲基類增加一些類型安全性(以及節省我的一些轉換)。

所以,我創建了一個類,這是(大約)這樣的:

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

所以,問題是:

是否有「通用」的方式從字符串轉換回原始?

我似乎無法找到任何通用接口,鏈接轉換板(類似ITryParsable將是理想!)。

+0

我很想看到你的具體類的例子,即使只是一個片段。 :) – 2008-08-12 09:54:03

+0

可以請你發佈你的基類的相關部分? – JJS 2012-07-11 21:26:08

回答

298

我不確定我是否正確理解你的意圖,但讓我們看看這個幫助。

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

我一直想知道幾天如何反序列化成一個泛型類型的流。謝謝:) – Trap 2008-09-30 22:13:09

+10

這隻適用於你的類型實現IConvertible – Kilhoffer 2010-01-11 14:46:31

+3

我同意,雖然`Convert.ChangeType`不是非常通用和可擴展的解決方案,它適用於大多數基本類型。如果需要更好的東西,將這種方法包裝成更像Tim的建議或完全使用不同的轉換方法是沒有問題的。 – 2010-01-11 15:11:52

3

你可以使用一個構造,如traits class。通過這種方式,您將擁有一個參數化的幫助類,它知道如何將字符串轉換爲其自己類型的值。然後你的getter可能是這樣的:

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

現在,我必須指出,我與參數化類型的經驗僅限於C++和它的模板,但我想有一些方法用做同樣的事情C#泛型。

+0

C#中不存在通用版本。 – Shimmy 2015-07-10 00:45:17

10

對於很多類型(整數,雙精度,DateTime等),有一個靜態的Parse方法。您可以使用反射來調用它:

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

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

lubos hasko的方法不能用於空值。下面的方法適用於可空數據。不過,我沒有想到它。我發現通過谷歌:http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx感謝 「金槍魚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))); 
    } 
} 
0
public class TypedProperty<T> : Property 
{ 
    public T TypedValue 
    { 
     get { return (T)(object)base.Value; } 
     set { base.Value = value.ToString();} 
    } 
} 

我使用經由將對象轉換。這有點簡單。

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

TypeDescriptor是具有方法GetConvertor類接受Type對象,然後就可以調用ConvertFrom方法將value轉換爲指定的對象。

0

我用lobos答案,它的工作原理。但由於文化背景,我在雙打轉換時遇到問題。所以我加了

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

檢查靜態Nullable.GetUnderlyingType。 - 如果基礎類型爲空,那麼模板參數不是Nullable,我們可以直接使用該類型 - 如果基礎類型不爲空,則在轉換中使用基礎類型。

似乎爲我工作:

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

另一種變型。句柄Nullables以及字符串爲空且T爲而非爲空的情況。

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