gpt4 book ai didi

C# 通用比较方法 [C++ 模板的模拟]

转载 作者:行者123 更新时间:2023-11-27 23:55:17 25 4
gpt4 key购买 nike

C++ 和 C# 都支持泛型。但是,我看不到任何方法可以将比较任意两个参数(arg1 > arg2?)的简单 C++ 函数模板重写为单个 C# 泛型方法:

C++

template<typename T>
int compare(const T & st1, const T & st2) {
if (std::less<T>() (st1, st2))
return -1;
return 1;
}

适用于 int , std::string , std::vector等等

compare(33, 4);         // 1

std::vector<int> v1{ 1,0 }, v2{ 1,0,0 };
compare(v1, v2); // -1

std::vector<std::string> vs1{ "hi", "bob" }, vs2{ "hi", "ben" };
compare(vs1, vs2); // 1

C#

   class Demo
{
public static int Compare<T>(T v1, T v2) where T : IComparable<T>
{
if (v1.CompareTo(v2) < 0)
return -1;
return 1;
}
}

不适用于 C# Lists<> :

List<int> v1 = new List<int> { 1, 2 };
List<int> v2 = new List<int> { 3, 4 };
Console.WriteLine($"Compare(v1, v2): {Compare(v1, v2)}");

错误:没有从“System.Collections.Generic.List”到“System.IComparable>”的隐式引用转换

让它在 C# 中同时处理整数类型和集合的唯一方法是每次都重载吗?

public static int Compare<T>(List<T> v1, List<T> v2) where T : IComparable<T>
{
for (int i = 0; i < v1.Count; i++)
{
if (v1[i].CompareTo(v2[i]) < 0)
return -1;
}
return 1;
}

最佳答案

错误的直接原因是List<int>没有实现 IComparer<List<int>>而这个事实不符合方法的规范:

public static int Compare<T>(T v1, T v2) where T : IComparable<T>

T必须实现 IComparable<T> .

我建议这样(快速且在某些情况下是肮脏的解决方案):

public static int Compare<T>(T v1, T v2, IComparer<T> comparer = null) {
if (null == comparer) // If we don't have tailored comparer
comparer = Comparer<T>.Default; // Try default one

// If we don't know how to compare - throw exception
if (null == comparer)
throw new ArgumentNullException("comparer",
$"Type {typeof(T).Name} doesn't have default comparer; comparer must not be null.");

// Taken from the question:
// if (v1.CompareTo(v2) < 0)
// return -1;
// return 1;
// You, probably, may want just
// return comparer.Compare(v1, v2);
return comparer.Compare(v1, v2) < 0 ? -1 : 1;
}

所以你可以把,在一个简单的例子中

int result = Compare(15, 25); // Comparer<int>.Default will be used

在没有默认比较器的复杂情况下,您必须实现它:

public class MyComparer<T> : IComparer<IEnumerable<T>> {
public int Compare(IEnumerable<T> x, IEnumerable<T> y) {
if (Object.ReferenceEquals(x, y))
return 0;
else if (null == x)
return -1;
else if (null == y)
return 1;

Comparer<T> comparer = Comparer<T>.Default;

using (var en_x = x.GetEnumerator()) {
using (var en_y = y.GetEnumerator()) {
if (!en_x.MoveNext())
if (!en_y.MoveNext())
return 0;
else
return 1;
else if (en_y.MoveNext())
return -1;

if (comparer != null) {
int result = comparer.Compare(en_x.Current, en_y.Current);

if (result != 0)
return result;
}
}
}

return 0;
}
}

并提供比较器

List<int> v1 = new List<int> { 1, 2 };
List<int> v2 = new List<int> { 3, 4 };

int another result = Compare(v1, v2, new MyComparer<int>());

关于C# 通用比较方法 [C++ 模板的模拟],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50734822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com