SingleOrDefault:在Custom结构上不返回null

时间:2012-09-11 13:17:26

标签: c# linq

我有结构,

public struct Test
{
    public int int1;
    public string str;
}

在我的代码中,我有,

List<Test> list = new List<Test>()
{ 
    new Test(){ int1 =1, str="abc" }, 
    new Test(){ int1 =2, str="abc" }
};

当我尝试在List<Test> list上使用具有搜索条件的SingleOrDefault时int1值等于3

Test result = list.SingleOrDefault(o => o.int1 == 3);

此处结果具有默认值的值,表示int1 = 0且str = null。如果不满足搜索条件,我希望null值。有人指点我怎么能这样做?

4 个答案:

答案 0 :(得分:5)

您不会返回null,因为Test是结构,值类型。将Test更改为类,它将返回null。

答案 1 :(得分:5)

值类型不可为空,因此您必须使用类或可以为空的Test?

但是如果你想坚持使用struct,你应该创建一个名为Empty的静态字段来检查空值:

public struct Test
{
    public static readonly Test Emtpy = new Test();
    public int int1;
    public string str;

    public static bool operator ==(Test a, Test b)
    {
        return a.int1 == b.int1 && Equals(a.str, b.str);
    }

    public static bool operator !=(Test a, Test b)
    {
        return !(a==b);
    }
}

这是一个可以在.Net框架中找到的约定。如果您以后想要检查null(您可能会做什么),请检查Test.Empty

List<Test> list = new List<Test>(){ new Test(){ int1 =1,str="abc"}, new Test(){ int1 =2,str="abc"}};
Test result = list.SingleOrDefault(o => o.int1 == 3);

if (result != Test.Emtpy)
    ...

答案 2 :(得分:3)

一个肮脏的修复:

    Test result = list.FirstOrDefault(o => o.int1 == 3);

    if (result.Equals(default(Test)))
    {
        // not found
    }
    else
    {
        // normal work
    }

只有在您确定原始列表永远不包含默认结构时才使用此选项(new Test(){int1 = 0,str = null})

答案 3 :(得分:0)

Test? result = list.Select(o => (?Test)o).SingleOrDefault(o => o.Value.int1 == 3);

它不漂亮,但它确实起作用。您可能希望将该模式提取为辅助方法。