2011-10-31 104 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(); } 
} 
相关问题