繁体   English   中英

从数据库转换并返回通用值

[英]Convert and Return generic value from database

我想从数据库返回值。 我定义了表格,其中每一列都定义了数据类型:

public enum TTableOffers
{
    [CStringValue("id")]
    [CType(typeof(Integer))]
    Id = 0,
    [CStringValue("project")]
    [CType(typeof(String))]
    ProjectId = 1,

}

因此,列“ id”的类型为Integer,“项目”的类型为String等。现在,我想通过此枚举从特定列获取值,如下所示:

    public T Value<T>(Enum enumColumn) where T : class // <<< class!
    {
        object aResult = m_aSqlDataReader.GetValue(columnIndex); // Here the aResult is filled with correct value (object) from database (working fine)

        ...     

        Type colType = CTypeAttribute.GetTypeValue(enumColumn); // Read the type from table - Integer or String (this is working fine)

        if (aResult == null) 
            return default(T);
        else
        {
           if (Convert.IsDBNull(aResult))
              return default(T);
           else
              aResult = ChangeType(aResult, colType); // Change the type to desired one --- here is the crash!!!                             
        }

        return (T)aResult;
       // here I also tried: return aResult as T;
    }

作为ChangeType方法,我使用以下方法: 从'System.Int32'到'System.Nullable`1 [[System.Int32,mscorlib]]的无效转换

类型为String的列可以正常工作,但是使用Integer时会出现问题。

由于无法使用Int32(结构),因此我定义了自己的类Integer,如下所示:

public class Integer : IComparable, IFormattable, IConvertible, IComparable<Integer>, IEquatable<Integer>
{
    int value = 0;

    public Integer(int value)
    {
        this.value = value;
    }

    // (Integer)123
    public static implicit operator Integer(int value)
    {
        return new Integer(value);
    }

    // (int)myInteger
    public static implicit operator int(Integer integer)
    {
        if (integer == null)
            integer = new Integer(default(int));

        return integer.value;
    }

    public static int operator +(Integer one, Integer two)
    {
        return one.value + two.value;
    }

    public static Integer operator +(int one, Integer two)
    {
        return new Integer(one + two);
    }

    public static int operator -(Integer one, Integer two)
    {
        return one.value - two.value;
    }

    public static Integer operator -(int one, Integer two)
    {
        return new Integer(one - two);
    }

    public static bool operator >(Integer one, int two)
    {
        return (int)one > two;
    }

    public static bool operator <(Integer one, int two)
    {
        return (int)one < two;
    }

    public static bool operator >(int one, Integer two)
    {
        return one > (int)two;
    }

    public static bool operator <(int one, Integer two)
    {
        return one < (int)two;
    }

    public TypeCode GetTypeCode()
    {
        throw new NotImplementedException();
    }

    public bool ToBoolean(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public byte ToByte(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public char ToChar(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public DateTime ToDateTime(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public decimal ToDecimal(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public double ToDouble(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public short ToInt16(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public int ToInt32(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public long ToInt64(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public sbyte ToSByte(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public float ToSingle(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public string ToString(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public object ToType(Type conversionType, IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public ushort ToUInt16(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public uint ToUInt32(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public ulong ToUInt64(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }

    public int CompareTo(object obj)
    {
        throw new NotImplementedException();
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {
        throw new NotImplementedException();
    }

    public int CompareTo(Integer other)
    {
        throw new NotImplementedException();
    }

    public bool Equals(Integer other)
    {
        throw new NotImplementedException();
    }
}

对于String,一切正常,但是对于Integer,我得到了“从'System.Int32'到'Code.Data.Integer'的无效转换。” 例外。

我在Integer类的每一行上都设置了断点,但没有人被击中。 我认为我在Integer类中缺少一些重要的东西,因为它从未被点击过并且没有完成转换。

我想念什么?

您的问题是您的值(在本例中为int )没有实现IConvertible接口。 从MSDN 文档中

ChangeType是一种通用的转换方法,它将由值指定的对象转换为conversionType。 value参数可以是任何类型的对象,conversionType也可以是表示任何基本或自定义类型的Type对象。 为使转换成功,值必须实现IConvertible接口 ,因为该方法只是将对一个合适的IConvertible方法的调用包装起来。 该方法要求支持将值转换为conversionType。

另外,从IConvertible的文档中:

如果实现IConvertible接口,则如果Object参数是实现类型的实例,而Type参数是公共语言运行时类型,则Convert.ChangeType方法将自动调用实现。

您以相反的方式称呼它:从CLR类型(int)到您的自定义类型,这将无法正常工作。

为什么不制作两个这样的Value方法:

public Nullable<T> Value<T>(Enum enumColumn) where T : struct {...}

public string Value(Enum enumColumn) {...}

第一个允许您返回空整数。

清洁得多,不是吗? :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM