回答(10 )。
2 years ago
将返回类型更改为Nullable,并使用非null参数调用该方法
staticvoidmain (字符串[ ] args ) )。
{
因? I=getvalueornull(null,string.Empty;
}
publicstaticnullablegetvalueornull (dbdatarecordreader,字符串列名称) where T : struct
{
对象列值=reader [ column name ];
if (! (columnValue is DBNull )
返回(t )列值;
返回空值;
}
2 years ago
publicstatictgetvalueordefault (隐藏数据记录器,索引) )。
{
object val=rdr [索引];
if (! (val is DBNull )
返回(t ) val;
返回默认值(t;
}
你只需要用它:
decimal? quantity=rdr.getvalueordefault (1;
string unit=rdr.getvalueordefault (2;
2 years ago
只需对原始代码执行两个操作。 删除where约束条件,并将最后一个返回从返回空值更改为返回默认值(t )。 现在,您可以返回到所需的类型。
顺便说一下,通过将if语句变更为if(columnvalue ),避免使用=dbnull.value(is )。
2 years ago
只是做和这个相似的难以置信的事。 我的代码:
Publictisnull(thisobjectvalue,T nullAlterative ) )。
{
if (值!=DBNull.Value )
{
类型类型=类型of (t;
if(type.isgenerictype
type.getgenerictypedefinition (==type of ) nullable ).getgenerictypedefinition ) )
{
type=nullable.getunderlyingtype (type;
}
return(t ) ) type.IsEnum? enum.toobject(type,convert.toint32 ) value ) :
convert.changetype(value,type );
}
else
返回空备用;
}
2 years ago
Disclaimer:此答案有效,但仅用于教育目的。 )詹姆斯琼斯' solutionisprobablythebesthereandcertainlytheonei '去吧。
如果不太安全,使用C#4.0的动态关键字会更容易。
publicstaticdynamicgetnullablevalue (thisidatarecordrecord,字符串列名称) )。
{
var val=reader[columnName];
return(val==dbnull.value? 空值: val;
}
其中,不需要在RHS中显式显示类型提示。
因? value=my datareader.getnullablevalue (my column name );
其实,你不需要那个!
varvalue=my datareader.getnullablevalue (' my column name );
value可以是int、字符串或DB返回的任何类型。
唯一的问题是,不妨碍在LHS中使用不能为空的类型。 这种情况下,执行时的异常会变得相当讨厌
,如:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot convert null to 'int' because it is a non-nullable value type
与使用 dynamic 的所有代码一样:告诫编码器 .
2 years ago
我想你想要处理引用类型和结构类型 . 我用它将XML Element字符串转换为更类型的字符串 . 您可以使用反射删除nullAlternative . formatprovider用于处理依赖于文化的' . '或','分隔符,例如小数或整数和双精度数 . 这可能有效:
public T GetValueOrNull(string strElementNameToSearchFor, IFormatProvider provider = null )
{
IFormatProvider theProvider = provider == null ? Provider : provider;
XElement elm = GetUniqueXElement(strElementNameToSearchFor);
if (elm == null)
{
object o = Activator.CreateInstance(typeof(T));
return (T)o;
}
else
{
try
{
Type type = typeof(T);
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition())
{
type = Nullable.GetUnderlyingType(type);
}
return (T)Convert.ChangeType(elm.Value, type, theProvider);
}
catch (Exception)
{
object o = Activator.CreateInstance(typeof(T));
return (T)o;
}
}
}
你可以像这样使用它:
iRes = helper.GetValueOrNull("top_overrun_length");
Assert.AreEqual(100, iRes);
decimal? dRes = helper.GetValueOrNull("top_overrun_bend_degrees");
Assert.AreEqual(new Decimal(10.1), dRes);
String strRes = helper.GetValueOrNull("top_overrun_bend_degrees");
Assert.AreEqual("10.1", strRes);
2 years ago
这可能是一个死线程,但我倾向于使用以下内容:
public static T? GetValueOrNull(this DbDataRecord reader, string columnName)
where T : struct
{
return reader[columnName] as T?;
}
2 years ago
我自己也遇到了同样的问题 .
... = reader["myYear"] as int?; 工作,很干净 .
它适用于任何类型,没有问题 . 如果结果是DBNull,则在转换失败时返回null .
2 years ago
我知道这是旧的,但这是另一种解决方案:
public static bool GetValueOrDefault(this SqlDataReader Reader, string ColumnName, out T Result)
{
try
{
object ColumnValue = Reader[ColumnName];
Result = (ColumnValue!=null && ColumnValue != DBNull.Value) ? (T)ColumnValue : default(T);
return ColumnValue!=null && ColumnValue != DBNull.Value;
}
catch
{
// Possibly an invalid cast?
return false;
}
}
现在,您不关心 T 是值还是引用类型 . 仅当函数返回true时,您才能从数据库中获得合理的值 . 用法:
...
decimal Quantity;
if (rdr.GetValueOrDefault("YourColumnName", out Quantity))
{
// Do something with Quantity
}
这种方法与 int.TryParse("123", out MyInt); 非常相似
2 years ago
多个通用约束不能以OR方式组合(限制性较小),仅以AND方式(更具限制性)组合 . 意味着一种方法无法处理这两种情况 . 通用约束也不能用于为方法创建唯一的签名,因此您必须使用2个单独的方法名称 .
但是,您可以使用通用约束来确保正确使用方法 .
在我的例子中,我特别希望返回null,而不是任何可能的值类型的默认值 . GetValueOrDefault =坏 . GetValueOrNull =好 .
我使用“Null”和“Nullable”这两个词来区分引用类型和值类型 . 这里是我编写的一些扩展方法的示例,它们补充了System.Linq.Enumerable类中的FirstOrDefault方法 .
public static TSource FirstOrNull(this IEnumerable source)
where TSource: class
{
if (source == null) return null;
var result = source.FirstOrDefault(); // Default for a class is null
return result;
}
public static TSource? FirstOrNullable(this IEnumerable source)
where TSource : struct
{
if (source == null) return null;
var result = source.FirstOrDefault(); // Default for a nullable is null
return result;
}