从object []转换始终返回Type,而不是value

时间:2013-10-23 04:18:57

标签: c# arrays types

我需要我的Criterion类在其构造函数中接受各种类型,并保留原始Type和每个类型的值。此术语中的参数数量范围为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:德米特里S建议进行一次测试,开辟了一条探索之路。我将Criterion称为“false”作为唯一的值[]参数。在立即窗口中,打印value.GetType()显示它正如预期的那样是一个Object []。 value [0] .GetType()将它显示为String []。虽然它最初是一个字符串,但我没有理想的原因。在这种情况下,IsArray是正确的。 当我用整数14调用它时,value [0] .GetType()显示一个非数组Int32。 到目前为止,打字是有道理的。但我有兴趣检索,而不是类型。

3 个答案:

答案 0 :(得分: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”
  • “(null)”如果值为null

希望它有所帮助。

答案 1 :(得分: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显示整个数组,请在"[" + String.Join(", ", Value) + "]"的{​​{1}}块中使用Value[0]或类似内容,而不是get,按照ivowiblo的回答。

答案 2 :(得分: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