我需要我的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。 到目前为止,打字是有道理的。但我有兴趣检索值,而不是类型。答案 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();
}
这将返回
希望它有所帮助。
答案 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