Reputation: 142
If I have an object containing a public int property (public accessors), how can I parse a string to int when initializing this property at instantiation ?
// Given initialized DataTable table;
// Given public int IntProperty {get; set;} in public class MyObject
table.Rows.Select(row => new MyObject
{
int.TryParse(row["stringValue"], IntProperty), // MyObject.IntProperty is unknown here
IntProperty = int.TryParse(row["stringValue"], ... ) // IntProperty is known but what about the out int result argument of Int32.TryParse ?
});
EDIT : I could do this but want to know if there is a way to do it directly inside object initializer :
table.Rows.Select(row => {
int.TryParse(row["stringValue"], out int intProperty);
return new MyObject
{
IntProperty = intProperty;
}
});
Upvotes: 4
Views: 834
Reputation: 17400
If you are sure, your stringvalue will always be parseable to int you can use int.Parse()
Otherwise, you will also have to handle a failed parsing. You can do like this:
out
parameter in the outer scope WARNING This will fail, if you traverse your list in parallel!
List<string> list = new List<string>{"1", "2", "3"};
int i = 0;
var ilist = list.Select(x => new MyObject {
IntProperty = int.TryParse(x, out i) ? i : 0
});
EDIT With inline declarations from VS2107 you can even do it without the variable from the outer scope
List<string> list = new List<string>{"1", "2", "3"};
var ilist = list.Select(x => new MyObject {
IntProperty = int.TryParse(x, out int i) ? i : 0
});
Upvotes: 1
Reputation: 34234
No, it is not possible to use out argument with object initializer.
You could just use Int.Parse
if you expect this row to always contain an integer, and then catch an exception. I would say that this the correct way to do this.
try
{
table.Rows.Select(row => new MyObject
{
IntProperty = int.Parse(row["stringValue"])
});
catch (FormatException)
{
// handle format exception
}
If you still want to use Int.TryParse
, then you would need to use body statement:
table.Rows.Select(row => {
bool parseResult = int.TryParse(row["stringValue"], out int x);
// TODO: handle parseResult! do not ignore it
return new MyObject
{
IntProperty = x
}
});
Upvotes: 0
Reputation: 37050
I strongly agree Jeroen Mostert. Instead of "squeezing everything into an object-initializer", make your code readable and easy to unserstand. Than it´ll probably compile without problems:
var result = new List<MyObject>();
foreach(var row in table.Rows)
{
var instance = new MyObject();
int value;
if(int.TryParse(row["stringValue"], out value)
instance.IntProperty = value;
result.Add(instance);
}
In C#7 you can also simplify this a bit to the following:
var instance = new MyObject();
if(int.TryParse(row["stringValue"], out int value)
instance.IntProperty = value;
result.Add(instance);
Upvotes: 2
Reputation: 1418
There is no way to do it in the way you are trying to do this, you need an intermediate variable to store the out value:
// Given initialized DataTable table;
// Given public int IntProperty {get; set;} in public class MyObject
table.Rows.Select((row) =>
{
if(int.TryParse(row["stringValue"], out int intValue)){
return new MyObject
{
IntProperty = intValue
};
}
else {
//do error handling
}
});
Upvotes: 0
Reputation: 101701
You will have to use out
variable to assign it back to IntProperty
, so I reckon there is no way to do it one statement inside of object initializer.
Either use int.Parse
or wrap the call to int.TryParse
in another utility method you create that returns in instead of bool and call it instead.
Upvotes: 0