2011-10-31 106 views
0

有比較兩個整數值的一些問題。做一個的CompareTo是給錯誤的對象的類型必須爲INT32

public interface IData 
{ 
    bool EqualsTo(IData otherData); 
} 

public class IntegerData : IData 
{ 
    int _data; 

    public IntegerData(int data) 
    { 
    _data = data; 
    } 

    public bool EqualsTo(IData otherData) 
    { 
    if(_data.CompareTo(otherData) == 0) 
     return true; 

    return false; 
    } 
} 

我得到一個錯誤在該行:

if(_data.CompareTo(otherData) == 0) 

說:

Object must of type int32 

但在我的觀察窗口,我可以看到這兩個值是10,並且類型爲int 。

怎麼了?

我的測試:

IData FirstData = new IntegerData(5); 
IData FirstData = new SecondData(5); 

bool result = FirstData.Value.EqualsTo(SecondData.Value); 
+1

'otherData'是類型的'IData',不'Int'。你可能想要'otherData._Data'。 –

回答

1

您在拋出異常的行的整數比較的IData對象。您需要將IData對象強制轉換爲IntegerData對象,然後進行比較時_data屬性與當地_data財產。

if(_data.CompareTo(((IntegerData)otherData)._data) == 0) 

更優雅的方法是使用泛型來處理您的不同類型的情況:

public interface IData<T> 
    { 
     bool EqualsTo(IData<T> otherData); 
    } 

    public class MyData<T> : IData<T> 
    { 
     private T _data; 

     public MyData(T data) 
     { 
      _data = data; 
     } 

     public bool EqualsTo(IData<T> otherData) 
     { 
      if (_data is IComparable 
       && otherData is MyData<T> 
       && ((IComparable)_data).CompareTo(((MyData<T>)otherData)._data) == 0) 
      { 
       return true; 
      } 
      return false; 
     } 
    } 

    static void Main(string[] args) 
    { 

     MyData<int> myInts1 = new MyData<int>(5); 
     MyData<int> myInts2 = new MyData<int>(5); 
     MyData<int> myInts3 = new MyData<int>(10); 
     MyData<string> myString1 = new MyData<string>("Hello"); 
     MyData<string> myString2 = new MyData<string>("Hello"); 
     MyData<string> myString3 = new MyData<string>("World"); 
     if (myInts1.EqualsTo(myInts2)) Console.WriteLine("Yay"); 
     if (!myInts1.EqualsTo(myInts3)) Console.WriteLine("Nay"); 
     if (myString1.EqualsTo(myString2)) Console.WriteLine("Yay"); 
     if (!myString1.EqualsTo(myString3)) Console.WriteLine("Nay"); 
    } 
+0

好的工作迴應我的界面示例。 – Gabe

+0

-1爲「你將不得不改變它的保護水平來做到這一點或創建一個公共財產訪問者」。你沒有。你從來不需要。閱讀關於這裏:http://stackoverflow.com/questions/614818/what-is-the-difference-between-public-private-protected-and-nothing –

+0

@LALALMMa - 我採取了將數據添加到接口的方法所以它必須默認公開。如果數據需要保持私有狀態,可以通過將EqualTo方法的otherData對象轉換爲期望的類來完成,然後以這種方式私密訪問它。 –

0

otherData的類型是IData

的你將不得不增加一個getter,讓您的int財產所以對於interface我添加GetData()方法 然後在IntegerData

實現了它

事情是這樣的:

public interface IData<T> 
{ 
    bool EqualsTo(IData otherData); 
    T GetData(); 
} 

public class IntegerData : IData<int> 
{ 
    int _data; 

    public int GetData(){ 
     return _data; 
    } 

    public IntegerData(int data) 
    { 
    _data = data; 
    } 

    public bool EqualsTo(IData otherData) 
    { 
    if(_data.CompareTo(otherData.GetData()) == 0) 
     return true; 

    return false; 
    } 
} 
+0

但GetData對於StringData:IData和其他類型將有所不同? – codecompleting

+0

我添加了泛型來解決這個問題。 – Gabe

+0

這是一條路。這也使我能夠從原始值創建一個哈希值(將GetData重命名爲GetDataHash)並僅比較哈希值。可能對索引等其他場景很有用。 –

3

我會嘗試儘可能簡單:

這是你在做什麼:

if (<intValue>.CompareTo(<IData object>) == 0) 
{ (...) } 

這是你所需要的:

if (<intValue>.CompareTo(<int value>) == 0) 
{ (...) } 

現在,這裏是你如何做到這一點(v ERY簡單的方式):

public bool EqualsTo(IData otherData) 
{ 
    if(_data.CompareTo(otherData._data) == 0) 
     return true; 
    return false; 
} 

這是另一種方式來達到同樣的(我會使用您的方案):

public interface IData : IEquatable<IData> { } 

public class IntegerData : IData 
{ 
    // The value will be private for this example 
    // Could be public int Value { get; private set; } 
    private int Value { get; set; } 

    // Constructor 
    public IntegerData(int value) { Value = value; } 

    // Implements Equals (from IEquatable - IData) 
    public bool Equals(IData other) 
    { return Value.Equals(other.Value); } 
} 

這是針對同一任務的另一個解決方案:
- 請記住,這是一個更大的r解決方案有點小問題。這可能會導致更大的類和更大的問題,所以只使用它,如果你需要它。簡單。保持簡單。不要陷入過於複雜的情況,因爲你必須隨着時間的推移維護這些代碼......
- 另請注意,我使用了默認的「GetHashCode」方法。有時這已經足夠了,但請記住,您可能需要根據需要創建/使用自定義哈希算法。
- 最後認爲這只是一個例子。我已經創建了基於Gabe的答案的接口,但僅爲哈希本身添加了一個方法。您可能想要刪除或改進。考慮你的需求。

// An interface that is based on IEquatable for better compatibility but also 
// enables you to create a diferent EqualsTo method... 
public interface IData<T> : IEquatable<T> 
{ 
    T GetData(); 
    int GetDataHash(); 
    bool EqualsTo(IData<T> other); 
} 

// One class (string) 
public class StringData : IData<string> 
{ 
    private string Value { get; set; } 

    public StringData(string value) { Value = value; } 

    public string GetData() { return Value; } 
    public int GetDataHash() { return GetData().GetHashCode(); } 

    // From IEquatable 
    public bool Equals(string other) 
    { return Value.Equals(other); } 

    // From IData (customized to compare the hash from raw value) 
    public bool EqualsTo(IData<string> other) 
    { return GetDataHash() == other.GetDataHash(); } 
} 

// Another class (int) 
public class IntData : IData<int> 
{ 
    private int Value { get; set; } 

    public IntData(int value) { Value = value; } 

    public int GetData() { return Value; } 
    public int GetDataHash() { return GetData().GetHashCode(); } 

    // Again from IEquatable 
    public bool Equals(int other) 
    { return Value == other; } 

    // Again from IData (customized to compare just the hash code) 
    public bool EqualsTo(IData<int> other) 
    { return GetDataHash() == other.GetDataHash(); } 
} 
相關問題