匿名实例化期间在对象初始化程序中输出参数

时间:2018-07-16 12:33:53

标签: c# out object-initializers

如果我有一个包含公共int属性(公共访问器)的对象,在实例化此属性时如何将字符串解析为int?

// 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 ?
});

编辑:我可以这样做,但想知道是否有一种方法可以直接在对象初始化程序内部进行:

table.Rows.Select(row => {
    int.TryParse(row["stringValue"], out int intProperty);
    return new MyObject 
    {
       IntProperty = intProperty;
    }
});

5 个答案:

答案 0 :(得分:0)

您将必须使用out变量将其分配回IntProperty,所以我认为无法在对象初始化器中执行一个语句。

使用int.Parse或将对int.TryParse的调用包装在您创建的另一个实用程序方法中,该方法返回的不是bool而是调用它。

答案 1 :(得分:0)

否,无法在对象初始化程序中使用out参数。

如果您希望该行始终包含一个整数,然后捕获异常,则可以使用Int.Parse。我会说这是正确的方法。

try
{
    table.Rows.Select(row => new MyObject 
    {
       IntProperty = int.Parse(row["stringValue"]) 
    });
catch (FormatException)
{
    // handle format exception    
}

如果您仍然想使用Int.TryParse,则需要使用body语句:

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
    }
});

答案 2 :(得分:0)

无法按照您尝试的方式进行操作,您需要一个中间变量来存储out值:

// 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
    }
});

答案 3 :(得分:0)

如果确定,您的字符串值将始终可以解析为int,可以使用int.Parse()

否则,您还必须处理失败的解析。您可以这样:

  • 在外部范围内定义out参数
  • 在成功解析的情况下在分配中使用

警告,如果您并行遍历列表,此操作将失败!

    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
    });

编辑,借助VS2107的内联声明,您甚至可以在没有外部作用域变量的情况下进行操作

    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
    });

答案 4 :(得分:0)

我非常同意Jeroen Mostert。而不是“将所有内容压缩到对象初始化程序中”,而是使您的代码具有可读性且易于理解。比它可能会毫无问题地编译:

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);
}

在C#7中,您还可以将其简化为以下内容:

var instance = new MyObject();
if(int.TryParse(row["stringValue"], out int value)
    instance.IntProperty = value;
result.Add(instance);