pet*_*loy 26 c# linq anonymous-types
我有任何Pilot带有(Hanger)属性的()对象数组,该属性可以为null,它本身具有(List<Plane>)属性.出于测试目的,我想简化并将其"展平"为具有属性PilotName(字符串)和Planes(数组)的匿名对象,但不确定如何处理null Hanger属性或空PlanesList.
(为什么是匿名对象?因为我正在测试的API的对象是只读的,我希望测试是'声明性的':自包含,简单和可读......但我对其他建议持开放态度.我也是我想了解更多有关LINQ的信息.)
例
class Pilot
{
public string Name;
public Hanger Hanger;
}
class Hanger
{
public string Name;
public List<Plane> PlaneList;
}
class Plane
{
public string Name;
}
[TestFixture]
class General
{
[Test]
public void Test()
{
var pilots = new Pilot[]
{
new Pilot() { Name = "Higgins" },
new Pilot()
{
Name = "Jones", Hanger = new Hanger()
{
Name = "Area 51",
PlaneList = new List<Plane>()
{
new Plane { Name = "B-52" },
new Plane { Name = "F-14" }
}
}
}
};
var actual = pilots.Select(p => new
{
PilotName = p.Name,
Planes = (p.Hanger == null || p.Hanger.PlaneList.Count == 0) ? null : p.Hanger.PlaneList.Select(h => ne
{
PlaneName = h.Name
}).ToArray()
}).ToArray();
var expected = new[] {
new { PilotName = "Higgins", Planes = null },
new
{
PilotName = "Jones",
Planes = new[] {
new { PlaneName = "B-52" },
new { PlaneName = "F-14" }
}
}
};
Assert.That(actual, Is.EqualTo(expected));
}
Run Code Online (Sandbox Code Playgroud)
当前的问题是线路expected... Planes = null错误,
无法指定匿名类型属性,但承认潜在的问题可能是使用
null在actual使用null不摆在首位的最佳方法.
任何想法如何可以分配在空阵列expected或采取不同的方式比null在actual?
And*_*tan 55
您必须使用类型化的 null:
(List<Plane>)null
Run Code Online (Sandbox Code Playgroud)
要么
(Plane[])null
Run Code Online (Sandbox Code Playgroud)
否则,编译器不知道您希望匿名类型的成员是什么类型.
更新
正如@AakashM正确地指出的那样 - 这解决了你给null匿名成员分配一个问题的问题- 但实际上并没有编译 - 如果确实如此,它将不允许你引用这些成员.
修复就是这样做(不幸的是null,匿名Planes数组都需要转换:
var expected = new[] {
new {
PilotName = "Higgins",
Planes = (IEnumerable)null
},
new {
PilotName = "Higgins",
Planes = (IEnumerable)new [] {
new { PlaneName = "B-52" },
new { PlaneName = "F-14" }
}
}
};
Run Code Online (Sandbox Code Playgroud)
因此请IEnumerable用作成员类型.您也可以使用,IEnumerable<object>但效果将相同.
或者 - 您可以使用IEnumerable<dynamic>常见类型 - 这可以让您这样做:
Assert.AreEqual("B-52", expected[1].Planes.First().PlaneName);
Run Code Online (Sandbox Code Playgroud)
Aak*_*shM 36
发生了两件事:
首先,当你构建使用匿名类型的实例new { Name = Value},以建设编译器需要能够制定出类型类型的Value.只是null它自己没有类型,所以编译器不知道给你的Planes成员什么类型.
现在,如果你使用命名类型作为值,你可以说(type)null并完成,但是因为你想要一个另一个匿名类型的数组,没有办法引用它(它是匿名的!).
那你如何null输入一个匿名类型的数组呢?好吧,C#规范保证了具有相同名称和类型(以相同顺序!)的成员的匿名类型是统一的 ; 也就是说,如果我们说
var a = new { Foo = "Bar" };
var b = new { Foo = "Baz" };
Run Code Online (Sandbox Code Playgroud)
然后a与b具有相同类型.我们可以使用这个事实来得到我们适当的类型null:
var array = (new[] { new { PlaneName = "" } });
array = null;
Run Code Online (Sandbox Code Playgroud)
它不漂亮,但它的工作原理 - 现在array有正确的类型但null 价值.所以这个编译:
var array = new[] { new { PlaneName = "" } };
array = null;
var expected = new[]
{
new
{
PilotName = "Higgins",
Planes = array
},
new
{
PilotName = "Higgins",
Planes = new[]
{
new { PlaneName = "B-52" },
new { PlaneName = "F-14" }
}
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20653 次 |
| 最近记录: |