0

你好MVC和LINQ专家,字段名称的列表作为一个字符串数组 - LINQ表达式

我有一个模型,看起来像这样:

public class SomeClass : IValidatableObject 
{ 
    public string SomeString { get; set; } 
    public string SomeString2 { get; set; } 
    public int SomeInteger { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     //... IF there is some error...THEN 
     yield return new ValidationResult("Some Error Message.", GetFieldNames(() => new []{ this.SomeString })); 
    } 

} 

正如你所看到的,我打电话GetFieldNames它接受一个表达式,并将表达式成员作为一个字符串数组返回给您。根据一本书我最近读,一个错误链接到一个字段的方法如下把它作为一个字符串:

yield return new ValidationResult("Some Error Message.", new []{ "SomeString" })); 

,但我想是强类型,所以这里是我写的方法:

public static string[] GetFieldNames(Expression<Func<object[]>> exp) 
    { 
     //Build a string that will in the end look like this: field1,field2,field3 
     //Then we split(',') it into an array and return that string array. 
     string fieldnames = ""; 

     MemberExpression body = exp.Body as MemberExpression; 

     if (body == null) 
     { 
      NewArrayExpression ubody = (NewArrayExpression)exp.Body; 
      foreach(MemberExpression exp2 in ubody.Expressions) 
      { 
       fieldnames += exp2.Member.Name + ","; 
      } 
      fieldnames = fieldnames.TrimEnd(','); 

     } 
     if(fieldnames.Length > 0) 
      return fieldnames.Split(','); 
     else 
      return new string[]{}; 
    } 

当前使用情况:

GetFieldNames(() => new[] { this.SomeString , this.SomeString2 });

输出:

{ "SomeString" , "SomeString2" }

这工作正常。

的问题是,如果我使用它,如下所示,它给了我一个错误(编译时间):

GetFieldNames(() => new[] { this.SomeString , this.SomeInteger });

错误: No best type found for implicitly-typed array

我所需的输出:

我不能在一个对象数组中传递因为int不是一个复杂的类型。

如何将函数的表达式数组传递给intstring

回答

1

你可以试着通过,而不是试图用一个数组初始化语法对象的数组(这是你的表达期望的内容):

GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger }); 

这允许你传递任意对象类型。

+0

是的!这样做..但我必须修复我的方法。查看我的答案以获得完整的解 – 2013-03-13 21:09:17

0

您可以定义一个接口IFieldName,该接口在您的列表中启用使用,然后在您的处理过程中出现的实际类型的不同类(int,错误,字符串等)中实现它。

这大致相当于定义一个对象的rray,但恢复类型安全。

0

随着达林迪米特里(想法的帮助来传递的,而不是new object[]new [] 下面的代码将确保您的IValidatableObject现在是强类型的,而不是只是一个字符串数组。

public static string[] GetFieldNames(Expression<Func<object[]>> exp) 
    { 
     string fieldnames = ""; 

     MemberExpression body = exp.Body as MemberExpression; 

     if (body == null) 
     { 
      NewArrayExpression ubody = (NewArrayExpression)exp.Body; 
      foreach (Expression exp2 in ubody.Expressions) 
      { 
       if (exp2 is MemberExpression) { 
        fieldnames += ((MemberExpression)exp2).Member.Name + ","; 
       } 
       else { 
        var op = ((UnaryExpression)exp2).Operand; 
        fieldnames += ((MemberExpression)op).Member.Name + ","; 
       } 
      } 
      fieldnames = fieldnames.TrimEnd(','); 

     } 

     if(fieldnames.Length > 0) 
      return fieldnames.Split(','); 
     else 
      return new string[]{}; 
    } 

用法:

GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger }));

使用MVC的验证:

yield return new ValidationResult("Some Error.", GetFieldNames(() => new object[] { this.SomeString, this.SomeInteger }));

相关问题