C# 从对象[]转换总是返回类型,而不是值

C# 从对象[]转换总是返回类型,而不是值,c#,arrays,types,C#,Arrays,Types,我需要我的Criteria类在其构造函数中接受各种类型,并保留原始类型和每个类型的值。这个术语中的参数数量可以从0到任意值 /* Examples of calls: var c = new Criterion("IsActive", OperationCode.EQUALS, false); var c = new Criterion("AgeRange", OperationCode.BETWEEN, 18, 35); */ public Criterion(string fi

我需要我的Criteria类在其构造函数中接受各种类型,并保留原始类型和每个类型的值。这个术语中的参数数量可以从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]);
}
在任何情况下,值的元素都返回System.String[],而不是它们的值。对于第一个示例调用,display将设置为IsActive EQUALS System.String[]。Convert.ToString(值[0])没有帮助,也没有帮助。想法

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

尝试以下方法:

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();
}
私有字符串GetValueAsString(对象obj)
{
if(obj==null)
返回“(空)”;
if(对象是IEnumerable)
{
var值=((IEnumerable)obj.Cast();
返回“{”+string.Join(“,”,values.Select(GetValueAsString))+“}”;
}
返回obj.ToString();
}
这会回来的

  • “2”代表2
  • “甜甜圈”代表“甜甜圈”
  • 值为1、2和3的数组的“{1,2,3}”
  • {{“Donut”,“Pie”}用于在第一个元素中具有字符串数组且值为“Donut”和“Pie”的数组
  • “(null)”如果值为null
希望有帮助。

试试这个:

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();
}
私有字符串GetValueAsString(对象obj)
{
if(obj==null)
返回“(空)”;
if(对象是IEnumerable)
{
var值=((IEnumerable)obj.Cast();
返回“{”+string.Join(“,”,values.Select(GetValueAsString))+“}”;
}
返回obj.ToString();
}
这会回来的

  • “2”代表2
  • “甜甜圈”代表“甜甜圈”
  • 值为1、2和3的数组的“{1,2,3}”
  • {{“Donut”,“Pie”}用于在第一个元素中具有字符串数组且值为“Donut”和“Pie”的数组
  • “(null)”如果值为null
希望有帮助。

试试这个:

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();
}
私有字符串GetValueAsString(对象obj)
{
if(obj==null)
返回“(空)”;
if(对象是IEnumerable)
{
var值=((IEnumerable)obj.Cast();
返回“{”+string.Join(“,”,values.Select(GetValueAsString))+“}”;
}
返回obj.ToString();
}
这会回来的

  • “2”代表2
  • “甜甜圈”代表“甜甜圈”
  • 值为1、2和3的数组的“{1,2,3}”
  • {{“Donut”,“Pie”}用于在第一个元素中具有字符串数组且值为“Donut”和“Pie”的数组
  • “(null)”如果值为null
希望有帮助。

试试这个:

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();
}
私有字符串GetValueAsString(对象obj)
{
if(obj==null)
返回“(空)”;
if(对象是IEnumerable)
{
var值=((IEnumerable)obj.Cast();
返回“{”+string.Join(“,”,values.Select(GetValueAsString))+“}”;
}
返回obj.ToString();
}
这会回来的

  • “2”代表2
  • “甜甜圈”代表“甜甜圈”
  • 值为1、2和3的数组的“{1,2,3}”
  • {{“Donut”,“Pie”}用于在第一个元素中具有字符串数组且值为“Donut”和“Pie”的数组
  • “(null)”如果值为null

希望能有所帮助。

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

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

如果您希望
显示
来显示整个数组,那么根据ivowiblo的回答,使用
“[”+字符串.连接(“,”,值)+“]”
或类似方法,而不是
获取
标准的
块中的
值[0]
。显示

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

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

如果您希望
显示
来显示整个数组,那么根据ivowiblo的回答,使用
“[”+字符串.连接(“,”,值)+“]”
或类似方法,而不是
获取
标准的
块中的
值[0]
。显示

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

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

如果您希望
显示
来显示整个数组,那么根据ivowiblo的回答,使用
“[”+字符串.连接(“,”,值)+“]”
或类似方法,而不是
获取
标准的
块中的
值[0]
。显示

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

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
显示t