LINQ之First,FirstOrDefault

返回LINQ大全首页

目录

  • First()
  • FirstOrDefault()

First()

First()基本用法相当于List[0]

public static TSource First (此IEnumerable 源);
MSDN

代码示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[] numbers = new int[] { 1, 2, 3, 5, 7, 11 };
        int result  = numbers.First();

        System.Console.WriteLine( "数据:{0}", numbers.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 
数据:[1], [2], [3], [5], [7], [11],
结果:1

First()可以通过在参数中指定条件,获取第一个满足条件的元素。

public static TSource First( this IEnumerable source, Func predicate );

让我们编写一个从数组中获取首个偶数的案例。

代码示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[] numbers = new int[] { 1, 2, 3, 5, 7, 11 };

        // 获取偶数
        int result  = numbers.First( value => value % 2 == 0 );

        System.Console.WriteLine( "数据:{0}", numbers.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

数据:[1][2][3][5][7][11],
结果:2

由于条件可以用lambda表达式编写,因此可以快速编写简单的条件。

现在,让我们编写一个从数组中搜索并获取具有指定名称的案例。

代码示例:

public static class Program
{
    private class Parameter
    {
        public int      ID      { get; set; }
        public string   Name    { get; set; }

        public override string ToString()
        {
            return string.Format( "ID:{0}, Name:{1}", ID, Name );
        }
    }

    static void Main( string[] args )
    {
        Parameter[] parameters = new Parameter[]
        {
            new Parameter() { ID =  5, Name = "正一郎" },
            new Parameter() { ID = 13, Name = "清次郎" },
            new Parameter() { ID = 25, Name = "誠三郎" },
            new Parameter() { ID = 42, Name = "征史郎" },
        };

        // Name为征史郎
        Parameter result    = parameters.First( value => value.Name == "征史郎" );

        System.Console.WriteLine( "数据:{0}", parameters.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 
数据:[ID5,名称:Seiichiro][ID13,名称:Seijiro][ID25,名称:Seisaburo][ID42,名称:Seishiro],
结果:ID:42名:征史郎

使用First()有两种情况会抛出异常,一种是序列为空的时候,会报错System.InvalidOperationException:序列不包含任何元素
另一种是没有元素符合条件的时候,会报错System.InvalidOperationException:该序列不包含匹配的元素

FirstOrDefault()

如果您不想四处写try-catch的话,用FirstOrDefault()可以解决这个问题。
它的作用是,在上述异常的情况下,将返回该类型的默认值

public static TSource FirstOrDefault( this IEnumerable source );
public static TSource FirstOrDefault( this IEnumerable source, Func predicate );
MSDN

代码示例:

public static class Program
{
    static void Main( string[] args )
    {
        int[] numbers = new int[] { 1, 2, 3, 5, 7, 11 };

        int result = 0;
        try
        {
            // 找比20大的值
            result = numbers.FirstOrDefault( value => value > 20 );
        }
        catch( System.Exception i_exception )
        {
            System.Console.WriteLine( "意外……:{0}", i_exception );

            System.Console.ReadKey();
            return;
        }        
        // 输出
        System.Console.WriteLine( "数据:{0}", numbers.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }
    
    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

数据:[1], [2], [3], [5], [7], [11],
结果:0

int型默认值为0,所以返回0。
那么序列是空的情况会怎么样呢?

代码示例:

public static class Program
{
    static void Main( string[] args )
    {
        // 空数组
        int[] numbers = new int[] { };

        int result = 0;
        try
        {
            result = numbers.FirstOrDefault();
        }
        catch( System.Exception i_exception )
        {
            System.Console.WriteLine( "意外……:{0}", i_exception );

            System.Console.ReadKey();
            return;
        }        

        // 输出
        System.Console.WriteLine( "数据:{0}", numbers.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

数据:
结果:0

这种情况下也不例外,同样是0
那么自己制作的数据类的序列情况怎么样呢?

代码示例:

public static class Program
{
    private class Parameter
    {
        public int      ID      { get; set; }
        public string   Name    { get; set; }

        public override string ToString()
        {
            return string.Format( "ID:{0}, Name:{1}", ID, Name );
        }
    }

    static void Main( string[] args )
    {
        Parameter[] parameters = new Parameter[]
        {
            new Parameter() { ID =  5, Name = "正一郎" },
            new Parameter() { ID = 13, Name = "清次郎" },
            new Parameter() { ID = 25, Name = "誠三郎" },
            new Parameter() { ID = 42, Name = "征史郎" },
        };

        Parameter result = new Parameter();
        try
        {
            result = parameters.FirstOrDefault( value => value.ID == 30 );
        }
        catch( System.Exception i_exception )
        {
            System.Console.WriteLine( "例外だよ……:{0}", i_exception );

            System.Console.ReadKey();
            return;
        }        

        // 输出
        System.Console.WriteLine( "数据:{0}", parameters.Text() );
        System.Console.WriteLine( "结果:{0}", result );

        System.Console.ReadKey();
    }

    public static string Text<TSource>( this IEnumerable<TSource> i_source )
    {
        string text = string.Empty;
        foreach( var value in i_source )
        {
            text += string.Format( "[{0}], ", value );
        }
        return text;
    }
} 

数据:[ID:5, Name:正一郎], [ID:13, Name:清次郎], [ID:25, Name:誠三郎], [ID:42,名称:征史郎] ,
结果:

class的预设值是null,所以结果是空的。

因为FirstOrDefault()不会发生意外,所以很方便。只是有需要注意的地方。如果是class等数据类型的话,没找到元素会返回空。

但是在数值型的情况下,替换值会变成某种总计的值,所以很难判断是否没有找到。在前面的示例中,如果找到偶数元素得到0,则不知道是找到了0元素还是没有找到,所以返回了预设值0。

你可能感兴趣的:(C#,c#,linq)