C# 当使用{value}语法初始化ICollection属性而不指定集合类型(数组、列表等)时会发生什么情况?

C# 当使用{value}语法初始化ICollection属性而不指定集合类型(数组、列表等)时会发生什么情况?,c#,.net,.net-core,C#,.net,.net Core,例如: 我删除了第一个花括号前面列出的new[]类型,并看到此代码仍按预期运行。我已经尝试将其复制到其他一些接口和类型。我很想知道背景中发生了什么,以及这种语法是如何工作的/为什么工作的,但我不太确定在我的搜索中使用哪些关键字。从您链接到的中,我们看到ICollection Fields属性在构造函数中被初始化为列表: // ///公共、共享查询选项 /// 公共公共查询选项(){ 字段=新列表(); FilterQueries=新列表(); 刻面=新的刻面参数(); ExtraParams

例如:

我删除了第一个花括号前面列出的
new[]
类型,并看到此代码仍按预期运行。我已经尝试将其复制到其他一些接口和类型。我很想知道背景中发生了什么,以及这种语法是如何工作的/为什么工作的,但我不太确定在我的搜索中使用哪些关键字。

从您链接到的中,我们看到
ICollection Fields
属性在构造函数中被初始化为
列表

//
///公共、共享查询选项
/// 
公共公共查询选项(){
字段=新列表();
FilterQueries=新列表();
刻面=新的刻面参数();
ExtraParams=新字典();
}
/// 
///要检索的字段。
///默认情况下,将返回所有存储的字段
/// 
公共ICollection字段{get;set;}
这允许初始值设定项语法按预期使用值


Fields=new[]{“*”,“score”}
所做的是用包含这些值的字符串数组替换该列表。这是因为.

请考虑下面的例子:

    public class UnitTest
{
    [Fact]
    public void TestList()
    {
        var sample = new SampleList
        {
            Fields = { "b", "c" }
        };

        var count = sample.Fields.Count;
        Assert.Equal(2, count);
    }

    [Fact]
    public void TestArray()
    {
        var sample = new SampleArray
        {
            Fields = { "b", "c" }
        };

        var count = sample.Fields.Count;
        Assert.Equal(2, count);
    }
}

public class SampleList
{
    public ICollection<string> Fields { get; set; } = new List<string>
    {
        "a"
    };
}

public class SampleArray
{
    public ICollection<string> Fields { get; set; } = new string[]
    {
        "a"
    };
}
公共类单元测试
{
[事实]
公共void测试列表()
{
var sample=新样本列表
{
字段={“b”,“c”}
};
var count=sample.Fields.count;
断言。相等(2,计数);
}
[事实]
公共无效测试阵列()
{
var sample=新的SampleArray
{
字段={“b”,“c”}
};
var count=sample.Fields.count;
断言。相等(2,计数);
}
}
公共类样本列表
{
公共ICollection字段{get;set;}=新列表
{
“a”
};
}
公共类抽样数组
{
公共ICollection字段{get;set;}=新字符串[]
{
“a”
};
}
您使用的语法仅在对象初始值设定项中有效,它尝试将指定项添加到集合中

  • 在TestList()中,测试用例assert失败,因为它将“b”、“c”添加到 列表和结果显示为“a”、“b”、“c”

  • 在TestArray()测试用例中,assert失败,因为它抛出以下命令 例外情况

System.NotSupportedException:“集合的大小是固定的。”


这意味着,如果要使用此对象初始化语法,必须使用大小不固定的集合。

实际上,这似乎会导致运行时出现NullReferenceException。我猜它并没有真正起作用,尽管编译(我认为是为了创建一个数组,而不是像你从new[]中所期望的那样)。它对我来说绝对有效。我使用的是SolrNet,当根据此信息生成查询字符串时,我可以使用这些结果看到它。我们可以看到此初始值设定项出现在其中的整个语句吗?查看源代码,我猜它可以工作,因为它下面是一个列表?我知道{}导致了对.Add的调用,但在您提出这个问题之前,我没有把它放在一起,或者(derp)想查看源代码。这就解释了为什么我不能复制它。在我的示例中,我没有初始化基础列表,因此.Add在第一次尝试时会失败,正如我所预料的那样,如果列表没有初始化的话。
    public class UnitTest
{
    [Fact]
    public void TestList()
    {
        var sample = new SampleList
        {
            Fields = { "b", "c" }
        };

        var count = sample.Fields.Count;
        Assert.Equal(2, count);
    }

    [Fact]
    public void TestArray()
    {
        var sample = new SampleArray
        {
            Fields = { "b", "c" }
        };

        var count = sample.Fields.Count;
        Assert.Equal(2, count);
    }
}

public class SampleList
{
    public ICollection<string> Fields { get; set; } = new List<string>
    {
        "a"
    };
}

public class SampleArray
{
    public ICollection<string> Fields { get; set; } = new string[]
    {
        "a"
    };
}