2013-10-23 86 views
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]); 
} 

在每種情況下,值的元素返回System.String [],而不是他們的價值。對於第一個示例調用,顯示將被設置爲IsActive EQUALS System.String []。 Convert.ToString(Value [0])沒有幫助,.ToString()也沒有幫助。想法?編輯#1:德米特里S提出了一個測試,打開了一個探索的途徑。我將Criterion與「false」作爲唯一值[]參數進行了調用。在即時窗口中,打印value.GetType()顯示它正如預期的那樣是一個Object []。 value [0] .GetType()顯示它是一個String []。雖然它最初是一個字符串,但我不理解爲什麼。在這種情況下,IsArray是真實的。 當我用整數14調用它時,值[0] .GetType()顯示一個非數組Int32。到目前爲止,打字很有意義。但我有興趣檢索,而不是類型。

+1

嘗試沒有'對象[]值=值;',只需值[0] – acelot

+1

你確定?我運行你的代碼,並且按照你的預期工作。使用這個:'string display = String.Format(「{0} {1} {2}」,FieldName,Op,Value [0]);'NOT this:'string display = String.Format(「{0} { 1} {2}「,FieldName,Op,Value);' –

+0

您是否從您的參數獲得了值,並對您的值進行空值檢查..... – Aravind

回答

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「}}」對於具有值1,2和3的數組,「
  • 」值「甜甜圈」和「餡餅」
  • 「(null)」如果該值爲空

希望它有幫助。

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) + "]"或類似代替Value[0]Criterion.displayget塊內,按照ivowiblo的回答。

0

編寫和運行在2010的VisualStudio以下修改後的代碼:

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 
相關問題