简体   繁体   English

将DataTable列类型传递给通用方法<T>

[英]Passing DataTable Column Type to generic method <T>

I have a method declared as such 我有一个这样声明的方法

public static T GetValidatedValue<T>(string param)
{
   do something here and return object of type T...;
}

usually I call it like this var somnum = GetValidatedValue("14"); 通常我这样称呼它var somnum = GetValidatedValue(“ 14”); and expect sumNum to be number or if an invalid value was passed to be "0" 并期望sumNum为数字,或者如果传递的无效值为“ 0”

my problem now is that I need to pass a datatabel column type as "T" into this method 我现在的问题是我需要将datatabel列类型作为“ T”传递给此方法

something like : 就像是 :

dr[col] = GetValidatedValue <typeof(dr[col])>(dr[col].ToString());

this will not compile 这将无法编译

it is basicaly a combination of two(2) methods that I have found somewhere(maybe even on this site) and modified to work as i needed 它基本上是我在某个地方(甚至在此站点上)找到并经过修改即可根据需要工作的两个(2)方法的组合

public static T GetValidatedValue<T>(string param)
{
    return TryParse<T>(param);
}

private static T TryParse<T>(string inValue)
{
    var converter = TypeDescriptor.GetConverter(typeof(T));

    try
    {
        return (T)converter.ConvertFromString(null, CultureInfo.InvariantCulture,     inValue);
    }
    catch
    {
        return default(T);
    }
}

can anyone shed some light on what I am doing wrong... 谁能告诉我我做错了什么...

How about the KISS method: KISS方法怎么样:

static readonly Dictionary<Type, object> defaultMap = new Dictionary<Type, object>()
        {
            { typeof(DateTime), DateTime.MinValue },
            { typeof(Int32), 0},
            { typeof(String), ""}
            /* etc etc etc*/
        };

private static void SetDefault(Type type, ref object value)
{
    if(value == DBNull.Value || value == null)
        value = defaultMap[type];
}

Then you just call it: 然后,您只需调用它:

SetDefault(col.DataType, ref dr[col]);

Generics are really only useful when you know what the type will be at compile time, in which case you can call your method like this: 泛型实际上仅在知道编译时的类型时才有用,在这种情况下,您可以这样调用方法:

GetValidatedValue<int>(dr[col].ToString());

However, it looks to me like you don't actually know the type at compile time, so generics would only get in the way. 但是,在我看来,您实际上在编译时并不知道类型,因此泛型只会妨碍您的工作。 Try implementing a non-generic version of your method, like this: 尝试实现方法的非泛型版本,如下所示:

public static object GetValidatedValue(string param, Type type)
{
    return TryParse(param, type);
}

private static object TryParse(string inValue, Type type)
{
    var converter = TypeDescriptor.GetConverter(type);

    try
    {
        return converter.ConvertFromString(null, CultureInfo.InvariantCulture, inValue);
    }
    catch
    {
        return default(T);
    }
}

That way you can call it like this: 这样,您可以这样称呼它:

GetValidatedValue<int>(dr[col].ToString(), dr[col].GetType());

(Although I must admit it seems like unnecessary overhead to turn something into a string and then convert it back to its original type again.) (尽管我必须承认,将某些内容转换为字符串然后再次将其转换回其原始类型似乎是不必要的开销。)

Update 更新资料

Now that I better understand what you're trying to do, the above method won't work because dr[col] will not have any type if it is null , and it will have the DbNull type if it is DbNull . 现在我更了解你想要做什么,上面的方法是行不通的,因为dr[col]不会有任何的类型,如果是null ,这将有DbNull类型,如果是DbNull Unless you have some other way to determine what type of data should be stored in that column, it's just not going to work. 除非您有其他方法来确定在该列中存储哪种类型的数据,否则它将无法正常工作。 Of course, if you can figure out what data type should be there, getting the default value will be totally easy: 当然,如果您可以确定应该使用哪种数据类型,则获取默认值将非常容易:

public static object GetValidatedValue(string param, Type type)
{
    return param == null || param == DBNull.Value ? Activator.CreateInstance(type); 
}

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

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