0

コンストラクターでさまざまな型を受け入れ、元の Type とそれぞれの値の両方を保持するには、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 は、調査の道を開くテストを提案しました。唯一の value[] 引数として「false」を指定して Criterion を呼び出しています。イミディエイト ウィンドウで value.GetType() を出力すると、予想どおり、それが Object[] であることがわかります。value[0].GetType() は、それが String[] であることを明らかにします。もともとは文字列ですが、この場合 .IsArray が true である理由がわかりません。整数 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" の配列の場合
  • 値が null の場合は "(null)"

それが役に立てば幸い。

于 2013-10-23T05:12:44.600 に答える
1

私はあなたの完全なソースを持っていませんが、空白のプロジェクトにインポートされた以下は、文字列と文字列の配列でさえ、2 つを混同することなく、小さな変更を加えて説明どおりに機能しました。

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]getCriterion.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 に答える