3

我想創建一個只能爲Serializable類運行的擴展。 是否有這樣的代碼:C#通用方法作爲擴展與where子句

using System; 

namespace ConsoleApplication2 
{ 
    [Serializable] 
    public class Ser 
    { 

    } 

    public class NonSer 
    { 

    } 

    public static class Extension 
    { 
     static public T f_DeepClone<T>(this T obj) 
          where T : (SerializableAttribute) 
     { 

      return (T) obj; 
     } 
    } 

    public class Program 
    { 
     static void Main(string[] args) 
     { 
      Ser mc = new Ser(); 
      mc.f_DeepClone<Ser>(); 
      NonSer mc1 = new NonSer(); 
      mc.f_DeepClone<NonSer>(); 
     } 
    } 
} 
+0

AFAIK你不能靜態檢查屬性 - 所以無論是嘗試使用了ISerializable或做代碼bzw.動態運行時檢查爲什麼'這個對象obj'而不是'this T obj'? – Carsten

+0

只能使用反射來檢查屬性。該類實際上並未實現該屬性。 – Aphelion

+0

@Aphelion,有沒有辦法檢查where子句? – uzay95

回答

1

您不能限制基於屬性的通用類型。

您將成爲使用代碼的人,然後您將知道對象何時可序列化以及何時不可以。編譯器不需要保護你。

但是,如果您要檢查在運行時,你可以這樣做:

static public T f_DeepClone<T>(this object obj) 
{ 
    if(typeof(T).IsSerializable == false) 
     throw new ArgumentException("Cannot clone non-serializable objects"); 

    // doing some serialization and deserialization 
    return (T) obj; 
} 
3

如果你想使用約束屬性,我認爲以下鏈接會有所幫助:

但是,如果你可以限制你使用ISerializable的領域,你可能不喜歡:

public static class Extension<T> 
{ 
    static public T f_DeepClone<T>(this object obj) where T: ISerializable 
    { 
     // doing some serialization and deserialization 
     return (T) obj; 
    } 
} 
+0

不是每個可序列化的類實現接口 – Aphelion

+0

@Ahelhelion,謝謝,我更新了答案! –

1

您不能測試的屬性,像你這樣的建議,但你可以測試接口:

public static class Extension 
{ 
    static public ISerializable f_DeepClone(this ISerializable obj) 
    { 
     // doing some serialization and deserialization 
     return (T) obj; 
    } 
}