我正在研究接口的类型,但我不明白如何使用 IEquatable接口。
我认为它提供了比直接使用 a.Equals(b)更好的性能,因为我们避免装箱......我已经这样做了:
public interface IEquatable<T> { bool Equals(T other); }
class Test<T> where T:IEquatable<T>
{
public static bool IsEqual(T a, T b) { return a.Equals(b); }
}
但是当我要打电话时,我在编辑中遇到错误,我不确定我是否正确调用该方法:
int x = 2;
int y = 2;
Console.WriteLine(Test.IsEqual(x, y));
错误是:
错误CS0305使用泛型类型'Test'需要1个类型参数
编辑:我对这段代码不是很确定,但它有效:
class Test<T> where T:IEquatable<T>
{
public static bool Equals(T a, T b)
{
return a.Equals(b);
}
}
class Program
{
static void Main(string[] args)
{
int x = 2;
int y = 2;
bool check = Test<int>.Equals(x, y);
Console.WriteLine(check);
Console.ReadKey();
}
}
我何时必须使用此代码?,我在 C#6 Nutshell O'reilly
一书中读到了这一点。答案 0 :(得分:3)
Test
不是 - 只有Test<T>
。您可以做的第一件事是使类型非泛型,方法泛型:
class Test
{
public static bool IsEqual<T>(T a, T b)
where T : IEquatable<T>
{ return a.Equals(b); }
}
请注意,这仍然不是很好 - 它不会a
作为null
正常工作,但是......这并不重要,因为它仍然无法帮助您,因为int
并未真正实现您的 IEquatable<T>
。它看起来不正确 - 它必须正式实现界面。幸运的是,int
为System.IEquatable<T>
实现内置 T==int
,所以只需完全删除您的界面定义。
但是,您在此处所做的一切都由EqualityComparer<T>.Default
做得更好。我建议:
class Test
{
public static bool IsEqual<T>(T a, T b)
=> EqualityComparer<T>.Default.Equals(a,b);
}
(请注意,您不需要通用约束 - 它仍可正常运行,在可用时使用IEquatable<T>
,否则使用object.Equals
- 也会占用null
,Nullable<T>
等。)
注意:如果真的只是在这里使用int
,那么您应该只使用==
:
Console.WriteLine(x == y);
当您只知道T
时,应使用通用的平等方法,其中来电者提供T
。
答案 1 :(得分:2)
问题是int
没有实现您的IEquatable<T>
界面。
在这里,我将向您介绍您的实施应该如何,但请考虑@MarcGravell在其答案中解释的内容:
public interface IEquatable<T>
{
bool Equals(T other);
}
public class MyInt : IEquatable<MyInt> //you need an actual implementor of IEquatable<T>
{
public int Value { get; set; }
public bool Equals(MyInt other)
{
return Value.Equals(other);
}
}
class Test
{
public static bool IsEqual<T>(T a, T b) where T : IEquatable<T>
{
// Ensure your Equals implementation is used
return a.Equals(b);
}
}
var x = new MyInt { Value = 2 };
var y = new MyInt { Value = 3 };
Test.IsEqual(x, y);
答案 2 :(得分:2)
您可以创建一个继承 IEquatable 的类。就像这样:
请注意,您必须定义ANY_TYPE。例如,它可以是字符串,int或DateTime。
public class Foo : IEquatable<ANY_TYPE>
{
...
}
现在因为你继承了一个提供方法的接口,你必须实现它。 只需将此函数放入类中:
public bool Equals(ANY_TYPE other)
{
if(other == null)return false; // Dont run into null reference trouble!
bool isSame = this == other; // or what ever you want to compare
return isSame;
}
您也可以使用通用类型。像这样创建你的类:
T是您正在处理的通用类型(有关详细信息,请参阅msdn generic types)
public class Foo<T> : IEquatable<T>
{
...
}
请注意,您必须将等于平均方法的 ANY_TYPE 更改为T!
我希望它可以帮到你。