Reputation: 1207
I have a piece of C# code where I have created an anonymous type object as follows:
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 }
};
Through LINQ I want to access the Ratio where Display="HEC" (case-insensitive) something like:
var multiplier = measurementUnits.Where(m => m.Display == "HEC").First().Ratio;
Upvotes: 1
Views: 2856
Reputation: 7054
One possible solution is to avoid dynamic
keyword. Try this code
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;
Also it would be better to replace First
with FirstOrDeafult
and manually test it for null, to avoid NullReference exception
var unit = measurementUnits.FirstOrDefault(m => m.Display.Contains("HEC"));
if (unit != null)
var multiplier = unit.Ratio();
Upvotes: 4
Reputation: 1433
You cand do this all with FirstOrDefault:
var multiplier = measurementUnits.FirstOrDefault(x => x.Display.Contains("H"))?.Ratio
Upvotes: 0
Reputation: 186668
Technically you can put something like this (please, note, that Display
is a collection which can Contain
but not be equal to a single item "H"
):
// 2.5
var multiplier = measurementUnits
.First(item => item.Display.Contains("H"))
.Ratio;
However, I recommend to use a custom class for this, not dynamic
which is prone for runtime errors (what if Display
is a string
, not List<string>
).
Edit: If there's a possibility that there's no such an item (say, "HEC2"
) and you don't want exception be thrown but a default value, change First
to FirstOrDefault
:
// 0.0 - default ratio, since "HEC2" is not found
var multiplier = measurementUnits
.FirstOrDefault(item => item.Display.Contains("HEC2"))
?.Ratio ?? 0 /* Default Ratio Value Here */;
Upvotes: 1
Reputation: 641
Contains would be your best option, yet static typing would be better and not using dynamic.
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;
Also you will need to check multiplier for null
as your using First
this will throw a null reference exception if no value is found, better solution:
var multiplier = measurementUnits.Where(m => m.Display.Contains("HEC")).FirstOrDefault()?.Ratio;
Upvotes: 1
Reputation: 5203
This is the solution:
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;
Upvotes: 0
Reputation: 18155
I believe you want to list where Display "has" "HEC", since it is a list. PS: It is unclear in your OP whether you want to filter by "H" or "HEC" (code and description dont match). Assuming it to be "HEC"
var result = measurementUnits.Where(x=>x.Display.Contains("HEC")).Select(x=>x.Ratio);
or If you want the first one
var result = measurementUnits.Where(x=>x.Display.Contains("HEC")).First().Ratio;
Upvotes: 0