0

我需要我的 Criterion 类在其构造函数中接受各种类型,并保留原始类型和每个类型的值。该术语中的参数数量可以从 0 到任何值。

/* Examples of calls:
   var c = new Criterion("IsActive", OperationCode.EQUALS, false);
   var c = new Criterion("AgeRange", OperationCode.BETWEEN, 18, 35);
*/

public Criterion(string fieldName, OperationCode op, params object[] value) {
    string FieldName = fieldName;
    OperationCode Op = op;
    object[] Value = value;
    string display = String.Format("{0} {1} {2}", FieldName, Op, Value[0]);
}

在任何情况下, Value 的元素都返回System.String[],而不是它们的值。对于第一个示例调用, display 将设置为IsActive EQUALS System.String[]。Convert.ToString(Value[0]) 没有帮助,.ToString()也没有帮助。想法?

编辑#1:Dmitry S 建议进行一项测试,开辟一条探索之路。我用“false”作为唯一的 value[] 参数来调用 Criterion。在即时窗口中,打印 value.GetType() 表明它如预期的那样是一个 Object[]。value[0].GetType() 显示它是一个 String[]。虽然它最初是一个字符串,但我不知道为什么 .IsArray 在这种情况下是真的。当我用整数 14 调用它时,value[0].GetType() 显示一个非数组 Int32。到目前为止,打字是有意义的。但我对检索感兴趣,而不是类型。

4

3 回答 3

2

尝试这个:

string display = String.Format("{0} {1} {{{2}}}", FieldName, Op, string.Join(", ", value));

如果你的数组看起来像

int[]{1, 2, 3, 4}

它会显示:

"field Equals {1, 2, 3, 4}"

编辑

如果您的值也可以是数组,则可能需要使用递归方法:

private string GetValueAsString(object obj)
{
    if(obj == null) 
         return "(null)";

    if(obj is IEnumerable)
    {
         var values = ((IEnumerable)obj).Cast<object>();
         return "{" + string.Join(", ", values.Select(GetValueAsString)) + "}";
    }

    return obj.ToString();
}

这将返回

  • “2”代表 2
  • “甜甜圈”换“甜甜圈”
  • "{1, 2, 3}" 表示值为 1、2 和 3 的数组
  • "{{"Donut", "Pie"}}" 表示在第一个元素中具有字符串数组的数组,其值为 "Donut" 和 "Pie"
  • 如果值为空,则为“(空)”

希望能帮助到你。

于 2013-10-23T05:12:44.600 回答
1

虽然我没有您的完整源代码,但导入到空白项目中的以下内容按所述进行了微小的更改,即使是在字符串和字符串数组上,也不会将两者混合:

class Program
{
    // not sure which other operations, so I just included these two
    public enum OperationCode { EQUALS, BETWEEN }

    // made class since it was used that way in your examples
    public class Criterion
    {
        // these have to be declared in the class, instead of the constructor to persist
        public string FieldName;
        public OperationCode Op;
        public object[] Value;

        // made this a property so that it will change automatically with FieldName, Op, and Value
        public string display { get { return String.Format("{0} {1} {2}", FieldName, Op, Value[0]); } }

        // constructor
        public Criterion(string fieldName, OperationCode op, params object[] value)
        {
            FieldName = fieldName;
            Op = op;
            Value = value;
        }
    }

    // main program tests with different values
    static void Main(string[] args)
    {
        Criterion c;

        c = new Criterion("IsActive", OperationCode.EQUALS, false);
        Console.WriteLine(c.display);
        Console.WriteLine(c.Value[0].GetType().ToString());
        Console.WriteLine();

        c = new Criterion("AgeRange", OperationCode.BETWEEN, 18, 35);
        Console.WriteLine(c.display);
        Console.WriteLine(c.Value[0].GetType().ToString());
        Console.WriteLine();

        c = new Criterion("TitleString", OperationCode.EQUALS, "This is the title.");
        Console.WriteLine(c.display);
        Console.WriteLine(c.Value[0].GetType().ToString());
        Console.WriteLine();

        Console.ReadLine();
    }
}

哪个输出:

IsActive EQUALS False
System.Boolean

AgeRange BETWEEN 18
System.Int32

TitleString EQUALS This is the title.
System.String

如果你想display显示整个数组,那么根据 ivowiblo 的回答,使用"[" + String.Join(", ", Value) + "]"or 类似的而不是Value[0]get块内。Criterion.display

于 2013-10-23T05:35:35.863 回答
0

在 VisualStudio 2010 上编译并运行以下修改后的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{


    public class Criterion
    {
        public static void Main()
        {
            // your code goes here
            var c = new Criterion("IsActive", OperationCode.EQUALS, false);
            c = new Criterion("AgeRange", OperationCode.BETWEEN, 18, 35);
            Console.ReadKey();

        }


        public Criterion(string fieldName, OperationCode op, params object[] value)
        {
            string FieldName = fieldName;
            OperationCode Op = op;
            object[] values = value;
            object val = values[0];
            string display = String.Format("{0} {1} {2}", FieldName, Op, values[0]);
            Console.WriteLine(display);
            Console.WriteLine(values[0].GetType().Name);
            Console.WriteLine(values.GetType().Name);
            Console.WriteLine(val.GetType().Name, val);
        }

    }

    public enum OperationCode
    {
        EQUALS,
        BETWEEN
    };

}

按预期输出:

IsActive EQUALS False
Boolean
Object[]
Boolean

AgeRange BETWEEN 18
Int32
Object[]
Int32
于 2013-10-23T06:28:20.627 回答