我有一个lambda表达式接受int?
(可以为空的整数),
如果值存在则返回值,否则返回DBNull.Value
。
Func<int?, object> getId = id => id.HasValue ? id.Value : (object)DBNull.Value;
这里的目标是,我想使该表达式略微更通用,以便我可以传递任何可以为空的类型,如DateTime?
所以这是我开始使用的非功能性代码,但不确定 where 指定nullable的类型。
int? imageId;
DateTime? actionDate;
Func<Nullable<T>, object> getValue =
id => id.HasValue ? id.Value : (object) DBNull.Value;
SaveImage(getValue(imageId), getValue(actionDate));
可以指定泛型类型,还是应该创建一个命名函数呢?
答案 0 :(得分:3)
由于问题的目的是使用lambda表达式,因此这是一个解决方案。通过使用弱类型而不是建议的强类型,它需要一条不同的路线,但仍然可以完成同样的事情。
// A lambda solution
Func<object, object> fnGetValue =
v =>
ReferenceEquals(v, null)
? DBNull.Value
: v;
// Sample usage
int? one = 1;
int? two = null;
object o1 = fnGetValue(one); // gets 1
object o2 = fnGetValue(two); // gets DBNull
编辑:这种松散的输入有效,因为lambda参数v的数据类型是struct本身,而不是Nullable类型的包装器。显然,调用者使用的Nullable值在到达lambda参数时已被解析或“解包”,并且lambda参数显示结构值或null; Nullable包装器在这一点上无处可见(或者据我所知)。可以通过在lambda中将调试断点放在v并检查其值来证明此行为。 这种行为的良好副作用是lambda同样适用于Nullable和非Nullable类型 - 它不受限制。
答案 1 :(得分:1)
您可以在Object上创建一个扩展方法来进行转换,而不是使用泛型。
这是一个示例程序。 ToDbObject扩展进行转换:
using System;
static class Program
{
static object ToDbObject(this object value)
{
return value ?? DBNull.Value;
}
static void Main(string[] args)
{
int? imageId = 3;
DateTime? actionDate = null;
Console.WriteLine("ImageId {0}: [{1}] - {2}", imageId, imageId.ToDbObject(), imageId.ToDbObject().GetType());
Console.WriteLine("actionDate {0}: [{1}] - {2}", actionDate, actionDate.ToDbObject(), actionDate.ToDbObject().GetType());
Console.ReadKey();
}
}
以上版画:
ImageId 3: [3] - System.Int32
actionDate : [] - System.DBNull
正确处理这两种情况。
答案 2 :(得分:1)
我认为您可以通过创建委托工厂方法来执行此操作,您可以在其中指定泛型类型参数:
public static Func<Nullable<T>, object> CreateGetValueFunc<T>() where T : struct
{
return id => id.HasValue ? id.Value : (object)DBNull.Value;
}
你可以在你的例子中使用它:
SaveImage(
CreateGetValueFunc<int>()(imageId),
CreateGetValueFunc<DateTime>()(actionDate));