2017-10-17 176 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))); 
     } 
    }