2012-07-31 131 views
0

我有一個NHibernate的IUserType,我試圖用來將一些固定大小的double []字段(不同大小)綁定到單個數據庫列作爲BLOB。我有下面的代碼,但不知何故,我需要傳遞一個常量整數,所以它知道數組應該是多大。我不認爲有一種方法可以在運行時以自定義的方式實例化這種類型,所以尺寸真的需要成爲類型本身的一部分。如果我能避免它,我寧願沒有這個醜陋類的兩個副本!傳遞一個常量作爲C#泛型類型參數

public class DoubleArrayUserType<Size> : NHibernate.UserTypes.IUserType 
{ 
    private int _size = sizeof(Size); 

    public object Assemble(object cached, object owner) 
    { 
     if (cached == null) 
      return null; 

     if (cached == DBNull.Value) 
      return null; 

     if (!(cached is byte[])) 
      throw new ArgumentException(); 

     var arrayBytes = cached as byte[]; 
     var arrayStream = new BinaryReader(new MemoryStream(arrayBytes)); 

     var values = new double[_size]; 
     for (int i = 0; i < _size; ++i) 
      values[i] = arrayStream.ReadDouble(); 

     return values; 
    } 

    public object Disassemble(object value) 
    { 
     if (value == null) 
      return DBNull.Value; 

     if (value == DBNull.Value) 
      return DBNull.Value; 

     if (!(value is double[])) 
      throw new ArgumentException(); 

     var values = value as double[]; 
     var bytes = new List<byte>(sizeof(double) * _size); 
     for (int i = 0; i < _size; ++i) 
      bytes.AddRange(BitConverter.GetBytes(values[i])); 
     return bytes.ToArray(); 
    } 

    public NHibernate.SqlTypes.SqlType[] SqlTypes 
    { 
     get { return new NHibernate.SqlTypes.SqlType[] { NHibernate.SqlTypes.SqlTypeFactory.GetBinaryBlob(1) }; } 
    } 
} 
+1

我假設你意識到你的問題的文字暗示你想要做一些在.Net中不可能的事情?你可能想考慮改變它。 – 2012-07-31 15:00:24

+3

你不能:它不是C++ ;-) – Seb 2012-07-31 15:00:58

+0

有沒有理由不能將arrayBytes的長度除以double的大小? – Neil 2012-07-31 15:02:49

回答

6

這是一個有爭議的解決方案(期待downvotes!),但它並沒有產生一個常數。我敢肯定,你將能夠解決您的問題以不同的方式,以及:

public interface IHasSize{ 
    int Size { get; } 
} 

public class MySize : IHasSize { 
    public int Size { get { return 4; } } 
} 

public class RequiresASize<TSize> where TSize : IHasSize, new() 
{ 
    private int _size = new TSize().Size; 
} 

public class ProvidesASize : RequiresASize<MySize>{ 
    //_size in base class will be 4 
} 

所以RequiresASize<TSize>是在你的問題你的大課。我在最後通過ProvidesASize類型使用繼承來演示它如何工作。

+0

你比我的詳細一點,但不像我的,它看起來像它會工作。 :P 'struct iTRAQArray {readonly double [] values = new double [8]; }結構TMTArray {只讀double [] values = new double [6];} struct TMTArray {readonly double [] values = new double [6]; } 公共類iTRAQArrayUserType:DoubleArrayUserType {} 公共類TMTArrayUserType:DoubleArrayUserType {}' – 2012-07-31 15:15:45

+0

我想你可以說這個技術類似於在升壓的確「新」 C++代碼中使用的整個「型特徵」的機制。我從來沒有想過要這樣做,我還沒有完全相信它不能以另一種方式完成;但是如果它工作,那麼很高興幫助:) – 2012-07-31 15:22:26

+0

即使'MySize4'和'SomeOtherSize4'通過返回來實現Size屬性,'RequiresASize '和'RequiresASize '的類型也不同4.你可以爲'RequiresASize '編寫一個靜態構造函數來檢查'TSize'類型是否永遠不是別人的類。 – 2012-07-31 15:31:17