【发布时间】:2010-10-07 04:30:40
【问题描述】:
我从 IEnumerable 中选择一个双精度值,我如何重载 FirstOrDefault() 函数,以默认返回 null,而不是零,我想要类似:
double? x = from ... .FirstOrDefault();
我现在可以捕获异常,并写入双倍? x = null,但我有 20 个变量,不是这样的
【问题讨论】:
标签: c# linq overloading
我从 IEnumerable 中选择一个双精度值,我如何重载 FirstOrDefault() 函数,以默认返回 null,而不是零,我想要类似:
double? x = from ... .FirstOrDefault();
我现在可以捕获异常,并写入双倍? x = null,但我有 20 个变量,不是这样的
【问题讨论】:
标签: c# linq overloading
不要捕获异常。异常的目的是告诉你你有一个错误,而不是充当控制流。
编写你自己的扩展方法来做你想做的事情是很简单的,那就这样做吧:
public static double? FirstOrNull(this IEnumerable<double> items)
{
foreach(double item in items)
return item;
return null;
}
或者,如果你想更喜欢它:
public static T? FirstOrNull<T>(this IEnumerable<T> items) where T : struct
{
foreach(T item in items)
return item;
return null;
}
有意义吗?
【讨论】:
为什么不直接做:
double? x = myDoubles.Cast<double?>().FirstOrDefault();
【讨论】:
您可以编写以下扩展方法, 我刚刚使用 Reflector 翻录了 FirstOrDefault 方法的代码并进行了修改以满足您的要求。
public static class MyExtension
{
public static TSource? NullOrFirst<TSource>(this IEnumerable<TSource> source) where TSource : struct
{
if (source == null)
{
throw new ArgumentNullException("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (list.Count > 0)
{
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current;
}
}
}
return null;
}
}
【讨论】:
我不知道您使用什么类型的查询。但如果您使用 IEnumerable,您可以尝试以下代码:
double? x = (/*Some IEnumerable here*/).OfType<double?>().FirstOrDefault();
但如果您关心性能,您最好使用扩展方法。
【讨论】:
如果我理解正确,您可以创建一个扩展方法来满足您的特定目的。
这将允许您使用语法:
double? d = ( linq expression ).MyCustomFirstOrNull();
http://msdn.microsoft.com/en-us/library/bb383977.aspx
有关扩展方法的一般语法,另请参阅此示例:
using System.Linq;
using System.Text;
using System;
namespace CustomExtensions
{
//Extension methods must be defined in a static class
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static int WordCount(this String str)
{
return str.Split(new char[] {' ', '.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}
namespace Extension_Methods_Simple
{
//Import the extension method namespace.
using CustomExtensions;
class Program
{
static void Main(string[] args)
{
string s = "The quick brown fox jumped over the lazy dog.";
// Call the method as if it were an
// instance method on the type. Note that the first
// parameter is not specified by the calling code.
int i = s.WordCount();
System.Console.WriteLine("Word count of s is {0}", i);
}
}
}
【讨论】: