怎么限制泛型的类型参数为int、decimal、datetime等基本类型?

橡木疙瘩 2014-12-18 01:39:53
写了这样一个泛型函数:

public static T? DbValueTo<T>(object value) where T : struct
{
T? result = null;
if (value != null && !(value is DBNull))
{
result = T.Parse(value.ToString());
}
return result;
}

结果编译错误(CS0119):“T”是一个“类型形参”,这在给定的上下文中无效 。

函数的目的是把从数据库中读出的值转为int?、datetime?等类型,如果数据库中是空,则返回值也要是空。
同时,由于要用同一段代码操作多个数据表,而有些数据表中类型定义得不规范,所以需要用Parse来进行转换。但是现在在T.Parse这一句出现了错误。
...全文
1574 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
蒋晟 2014-12-21
  • 打赏
  • 举报
回复
泛型限制必须是接口、非密封类或者类型*class或者struct)。基本类型哪一种都不符合。.Net的类型系统并不允许从基本类型派生。所以不让你限制基本类型。 但是你可以模拟一下,因为Int32是这么定义的 public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int> 你可以这么写: where T:IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T> 这样虽然没有达到你的要求,但是比where T:struct更严格一些。真要检测的话,你可以在调试版代码里检测typeof(T)之后碰见不支持的类型就抛异常。
effun 2014-12-19
  • 打赏
  • 举报
回复 1
即使能够限制泛型参数是基元类型,也不可能调用T.Parse。我想楼主的本意是要将传入参数value转换为目标类型T,假如说value本身就是T类型的,就不用这么复杂,直接进行强制类型转换即可。 result = new Nullable<T>((T)value); 假如value有可能不是要转换的目标类型,那就要进行类型转换,关于类型转换有多种办法以下几个办法仅供参考。 1、使用Convert.ChangeType方法。 2、通过反射调用Parse方法。 3、使用TypeConverter。 可能依次尝试以上几种方法来实现类型转换。
wangyue4 2014-12-19
  • 打赏
  • 举报
回复

 public class MyClass2<T>
        where T : struct//这个泛型类只接受值类型的泛型参数
    { 
    }
游离失所 2014-12-18
  • 打赏
  • 举报
回复


 public class ConvertStruts
        {
            static ConvertStruts()
            {
                Cache<int>.Convert = (x) => Convert.ToInt32(x);
                Cache<long>.Convert = (x) => Convert.ToInt64(x);
            }

            private static class Cache<TResult>
            {
                public static Func<object, TResult> Convert;
            }

            public static T? DbValueTo<T>(object value) where T : struct
            {
                T? result = null;
                if (value != null && !(value is DBNull))
                {
                    result = Cache<T>.Convert(value);
                }
                return result;
            }
        }

        static void Main(string[] args)
        {
            var a = ConvertStruts.DbValueTo<int>("123");
        }

这样也行,这种更好。。但你要理解下
游离失所 2014-12-18
  • 打赏
  • 举报
回复


 public static T? DbValueTo<T>(object value) where T : struct
            {
                T? result = null;
                if (value != null && !(value is DBNull))
                {
                    result = (T?)Convert.ChangeType(value, typeof(T));
                }
                return result;
            }
ajaxfeifei 2014-12-18
  • 打赏
  • 举报
回复
暂时没有办法限制,我已经做过这类的开发了。也找过很多办法,给你参考一下

        public T GetValue<T>(object value, T defaultvalue = default(T))
        {
            if (value== null || value== DBNull.Value)
            {
                return defaultvalue;
            }
            return (T)value;
        }
exception92 2014-12-18
  • 打赏
  • 举报
回复
这个不可以吧,基本类型都没有所谓的“父类”
phommy 2014-12-18
  • 打赏
  • 举报
回复
微软没有提供IParsable接口,只能换思路: //result = T.Parse(value.ToString()); 改成下边这行 result = Convert.ChangeType(value, typeof(T)) as T?;

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧