2017-10-17 29 views
0

我在寫一個自定義泛型VectorN類,其中T:struct,IFormattable,IComparable,IConvertible。 我可以通過此[int index]訪問矢量的索引值。因此,在一個循環中我做這一塊的代碼,以使VectorN.One:從int轉換爲自定義結構C#

r[i] = (T)Convert.ChangeType(1, typeof(T)); 

它與標準的數字如int,小數,等完美的作品,但是當我寫了測試自定義結構uHalfByte,它給出了一個錯誤:

Invalid cast from 'System.Int32' to 'uHalfByte'.

這裏是uHalfByte的腳本:

struct uHalfByte : IFormattable, IComparable<uHalfByte>, IConvertible 
{ 
    private byte val; 
    public byte Val 
    { 
     get { return (byte)(val & 0xF); } 
     set { val = (byte)(value & 0xF); } 
    } 
    public uHalfByte(byte val) 
    { 
     this.val = (byte)(val & 0xF); 
    } 

    public string ToString(string format, IFormatProvider formatProvider) 
    { 
     if (formatProvider == null) formatProvider = System.Globalization.CultureInfo.CurrentCulture; 
     if (string.IsNullOrEmpty(format)) format = "G"; 
     string s = ""; 
     for (int i = 0; i < 4; i++) s += ((Val >> i) & 1).ToString(format,formatProvider); 
     return s; 
    } 

    public int CompareTo(uHalfByte other) 
    { 
     return this.Val - other.Val; 
    } 

    public TypeCode GetTypeCode() 
    { 
     return TypeCode.Byte; 
    } 

    public bool ToBoolean(IFormatProvider provider) 
    { 
     return val!=0; 
    } 

    public char ToChar(IFormatProvider provider) 
    { 
     return (char)val; 
    } 

    public sbyte ToSByte(IFormatProvider provider) 
    { 
     return (sbyte)val; 
    } 

    public byte ToByte(IFormatProvider provider) 
    { 
     return (byte)val; 
    } 

    public short ToInt16(IFormatProvider provider) 
    { 
     return (short)val; 
    } 

    public ushort ToUInt16(IFormatProvider provider) 
    { 
     return (ushort)val; 
    } 

    public int ToInt32(IFormatProvider provider) 
    { 
     return (int)val; 
    } 

    public uint ToUInt32(IFormatProvider provider) 
    { 
     return (uint)val; 
    } 

    public long ToInt64(IFormatProvider provider) 
    { 
     return (long)val; 
    } 

    public ulong ToUInt64(IFormatProvider provider) 
    { 
     return (ulong)val; 
    } 

    public float ToSingle(IFormatProvider provider) 
    { 
     return (float)val; 
    } 

    public double ToDouble(IFormatProvider provider) 
    { 
     return (double)val; 
    } 

    public decimal ToDecimal(IFormatProvider provider) 
    { 
     return (decimal)val; 
    } 

    public DateTime ToDateTime(IFormatProvider provider) 
    { 
     return new DateTime(val); 
    } 

    public string ToString(IFormatProvider provider) 
    { 
     return ToString("", provider); 
    } 

    public object ToType(Type conversionType, IFormatProvider provider) 
    { 
     return Convert.ChangeType(val, conversionType); 
    } 

    public static explicit operator uHalfByte(int val) 
    { 
     return new uHalfByte((byte)val); 
    } 
} 

難道我做錯事的uHalfByte或者它僅僅是不可能的?

回答

0

它不會以這種方式工作,因爲System.Int32(如異常消息說明)對您的自定義類沒有信息uHalfByte,不能執行轉換。 當然,它的工作是另一種方式uHalfByte - > INT

編輯:
在你的情況,我認爲你可以使用轉換操作符: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/using-conversion-operators

這樣的:

struct uHalfByte 
{ 
    public static explicit operator uHalfByte(int value) 
    { 
     return new uHalfByte(); 
    } 
    public static explicit operator uHalfByte(string value) 
    { 
     return new uHalfByte(); 
    } 
} 

用法:

if (typeof(T) == typeof(uHalfByte)) 
    r[i] = (uHalfByte)value; 
else 
    r[i] = (T)Convert.ChangeType(value, typeof(T)); 
+0

但是沒有選項來實現構造函數一個結構接口,沒有選擇使用抽象類作爲struct的基礎。 IMyConvertibleExample應該如何? – mcmikecreations

0

基於@Thowk的回答解決辦法: 實現一個通用的接口:

public interface INumber<T> 
{ 
    T ConvertGeneric<T1>(T1 item); 
} 

加在我的腳本接口的實現:

public struct uHalfByte : IFormattable, IComparable<uHalfByte>, IConvertible, INumber<uHalfByte> 
    { 
     ... 
     public uHalfByte ConvertGeneric<T>(T item) 
     { 
      if (typeof(T) == typeof(int)) 
      { 
       return new uHalfByte((byte)(int)Convert.ChangeType(item, typeof(int))); 
      } 
      else if (typeof(T) == typeof(uint)) 
      { 
       return new uHalfByte((byte)(uint)Convert.ChangeType(item, typeof(uint))); 
      } 
      else if (typeof(T) == typeof(long)) 
      { 
       return new uHalfByte((byte)(long)Convert.ChangeType(item, typeof(long))); 
      } 
      else if (typeof(T) == typeof(ulong)) 
      { 
       return new uHalfByte((byte)(ulong)Convert.ChangeType(item, typeof(ulong))); 
      } 
      else if (typeof(T) == typeof(short)) 
      { 
       return new uHalfByte((byte)(short)Convert.ChangeType(item, typeof(short))); 
      } 
      else if (typeof(T) == typeof(ushort)) 
      { 
       return new uHalfByte((byte)(ushort)Convert.ChangeType(item, typeof(ushort))); 
      } 
      else if (typeof(T) == typeof(byte)) 
      { 
       return new uHalfByte((byte)Convert.ChangeType(item, typeof(byte))); 
      } 
      else if (typeof(T) == typeof(sbyte)) 
      { 
       return new uHalfByte((byte)(sbyte)Convert.ChangeType(item, typeof(sbyte))); 
      } 
      else throw new NotSupportedException(string.Format("Type {0} is not supported, you have to write your own function!", typeof(T))); 
     } 
    }