对包含动态列表的匿名类型的C#LINQ查询

时间:2019-02-01 09:55:03

标签: c# list linq dynamic anonymous-types

我有一段C#代码,在其中创建了一个匿名类型对象,如下所示:

    var measurementUnits = new List<dynamic>() {
    new { Unit = "SQF", Display = new List<string>() { "F", "FT", "SQ FT" }, Ratio=1.5 } ,
    new { Unit = "Hectares", Display = new List<string>() { "H", "HEC"} , Ratio=2.5},
    new { Unit = "Acres", Display = new List<string>() { "AC(TO)" } , Ratio=3.5},
    new { Unit = "SQM", Display = new List<string>() {  "M", "SQ M"}, Ratio=4.5 }
};

我要通过LINQ访问 比率 ,其中 Display =“ HEC” (不区分大小写)如下:

var multiplier = measurementUnits.Where(m => m.Display == "HEC").First().Ratio;

6 个答案:

答案 0 :(得分:3)

一种可能的解决方案是避免使用dynamic关键字。试试这个代码

var measurementUnits = new [] {
    new { Unit = "SQF", Display = new List<string>() { "F", "FT", "SQ FT" }, Ratio=1.5 } ,
    new { Unit = "Hectares", Display = new List<string>() { "H", "HEC"} , Ratio=2.5},
    new { Unit = "Acres", Display = new List<string>() { "AC(TO)" } , Ratio=3.5},
    new { Unit = "SQM", Display = new List<string>() {  "M", "SQ M"}, Ratio=4.5 }
};

var multiplier = measurementUnits.Where(m => m.Display.Contains("HEC")).First().Ratio;

另外,最好将First替换为FirstOrDeafult并手动测试其是否为null,以避免NullReference异常

var unit = measurementUnits.FirstOrDefault(m => m.Display.Contains("HEC"));
if (unit != null)
    var multiplier = unit.Ratio();    

答案 1 :(得分:1)

从技术上讲,您可以输入以下内容(请注意,Podfile.lock是可以Display但不等于单个项目Contain的集合):

"H"

但是,我建议为此使用自定义类,而不要使用容易发生运行时错误的 // 2.5 var multiplier = measurementUnits .First(item => item.Display.Contains("H")) .Ratio; (如果dynamicDisplay,不是string)。

编辑::如果没有这样的项目(例如List<string>),并且您不希望抛出 exception ,而是默认值,将"HEC2"更改为First

FirstOrDefault

答案 2 :(得分:1)

包含是您的最佳选择,但是静态键入会更好,并且不使用动态。

What is the difference between statically typed and dynamically typed languages?

var measurementUnits = new List<dynamic>() {
     new { Unit = "SQF", Display = new List<string>() { "F", "FT", "SQ FT" }, Ratio=1.5  ,
     new { Unit = "Hectares", Display = new List<string>() { "H", "HEC"} , Ratio=2.5 },
     new { Unit = "Acres", Display = new List<string>() { "AC(TO)" } , Ratio=3.5},
     new { Unit = "SQM", Display = new List<string>() { "M", "SQ M"}, Ratio=4.5 } 
};

var multiplier = measurementUnits.Where(m => m.Display.Contains("HEC")).First().Ratio;

另外,您将需要检查null的乘数,因为使用First会导致找不到值的情况下引发空引用异常,这是更好的解决方法:

var multiplier = measurementUnits.Where(m => m.Display.Contains("HEC")).FirstOrDefault()?.Ratio;

答案 3 :(得分:0)

我相信您希望列出Display“具有”“ HEC”的位置,因为它是一个列表。 PS:尚不清楚您的OP中是否要按“ H”或“ HEC”进行过滤(代码和说明不匹配)。假设它是“ HEC”

'template-curly-spacing': ['error', 'never']

或 如果要第一个

var result = measurementUnits.Where(x=>x.Display.Contains("HEC")).Select(x=>x.Ratio);

答案 4 :(得分:0)

这是解决方案:

var measurementUnits = new [] {
    new { Unit = "SQF", Display = new List<string>() { "F", "FT", "SQ FT" }, Ratio=1.5 } ,
    new { Unit = "Hectares", Display = new List<string>() { "H", "HEC"} , Ratio=2.5},
    new { Unit = "Acres", Display = new List<string>() { "AC(TO)" } , Ratio=3.5},
    new { Unit = "SQM", Display = new List<string>() {  "M", "SQ M"}, Ratio=4.5 }
};
var multiplier = measurementUnits.Where(m => m.Display.IndexOf("H") > -1).FirstOrDefault()?.Ratio;

答案 5 :(得分:0)

您可以使用FirstOrDefault做到这一切:

 var multiplier = measurementUnits.FirstOrDefault(x => x.Display.Contains("H"))?.Ratio