我可以指定"或"关键字"where"泛型类型参数约束
本文关键字:quot where 泛型类型 参数约束 关键字 我可以 | 更新日期: 2023-09-27 18:03:01
我有一个函数来做打乱比较
public static int ScrambledEquals<TKey, T>(
IDictionary<TKey, T> list1,
IDictionary<TKey, T> list2)
where TKey : IComparable
where T : ICompareAsHtml or IComparable // compilation failure on this line
{
// ...
}
public static int ScrambledEquals<TKey, T>(
IDictionary<TKey, T> list1,
IDictionary<TKey, T> list2)
where TKey : IComparable
where T : ICompareAsHtml {} // This works!
TKey必须是icomable,但是值类型T可以是icomable或者在接口
下面实现 public interface ICompareAsHtml
{
// Compare current "this" object with "obj"
// and persist the difference in html somewhere
// return number of differences.
int compareAsHtml(object obj);
}
我如何更新where行使编译通过(不删除它,不使用其中一个接口)?
或者更好,你可以阅读下面我的代码来了解我的情况。我需要使用下面的函数来比较字符串的集合,这是IComparable;或者比较一个拥抱类的集合,比如Sales,它实现了icompareashhtml,但没有IComparable。(因为太多的属性使得这个类很难实现CompareTo函数-不能给出"一个"数字来表示两个实例之间的"方向"answers"距离")
public static int ScrambledEquals<TKey, T>(
IDictionary<TKey, T> list1,
IDictionary<TKey, T> list2)
where TKey : IComparable
// where T : ICompareAsHtml or IComparable
// commented out above line to make compilation pass
{
int nDIff = 0;
List<TKey> bothKeys = list1.Keys.Union<TKey>(list2.Keys).ToList();
bothKeys.Sort();
foreach (TKey key in bothKeys)
{
// code omitted - not related to this question
{
// key exist in both lists.
object o1 = list1[key];
object o2 = list2[key];
if (o1 is IComparable && o2 is IComparable)
{
IComparable v1 = (IComparable)o1;
IComparable v2 = (IComparable)o2;
if (0 != v1.CompareTo(v2))
{
nDIff++;
// Save the difference in html
}
}
else if (o1 is ICompareAsHtml && o2 is ICompareAsHtml)
{
ICompareAsHtml v1 = (ICompareAsHtml)o1;
ICompareAsHtml v2 = (ICompareAsHtml)o2;
// Save the difference
nDIff += v1.compareAsHtml(v2);
}
else
{
// If I can use where keyword
// I don't need this exception
throw new Exception(@"Error: Program error
- Value Type is neither IComparable nor ICompareAsHtml.");
}
}
}
}
return nDIff;
}
欢迎所有建议/反馈/评论!
这不是框架支持的。然而,这样做的需要意味着缺少一个IComparable
和ICompareAsHtml
都应该实现的公共接口,而您可以约束它。
IComparable
是框架的一部分,这意味着你不能改变它来实现缺失的接口。好消息是IComparable
已经相当简单了……也许就是那个缺失的接口。
ICompareAsHtml
不是框架的一部分,并且我目前可以通过Google搜索的任何产品的文档中都没有提到,这意味着它可能是一个您可以更改的接口。如果这是真的,只要让ICompareAsHtml
实现IComparable
,只约束IComparable
,你就会满足你的条件
您不能在约束列表上执行OR操作,请查看此处的文档:https://msdn.microsoft.com/en-us/library/d5x73970.aspx
也许你可以让你的接口派生自IComparable:
public interface ICompareAsHtml : IComparable
{
int compareAsHtml(object obj);
}
class CompareAsHtml : ICompareAsHtml
{
public int CompareTo(object obj)
{
return compareAsHtml(obj);
}
public int compareAsHtml(object obj)
{
//do the core comparison here and return
}
}
最后,我想出了使用两个函数而不是一个
public static int ScrambledEqualsComparable<TKey, T>(
IDictionary<TKey, T> list1,
IDictionary<TKey, T> list2)
where TKey : IComparable
where T : IComparable
{
return ScrambledEquals(list1, list2);
}
public static int ScrambledEqualsCompareAsHtml<TKey, T>(
IDictionary<TKey, T> list1,
IDictionary<TKey, T> list2)
where TKey : IComparable
where T : ICompareAsHtml
{
return ScrambledEquals(list1, list2);
}
private static int ScrambledEquals<TKey, T>(
Dictionary<TKey, T> list1,
Dictionary<TKey, T> list2)
where TKey : IComparable
{
// the same as above code - No need to throw exception as
// it has to be one of ICompareAsHtml or IComparable.
}
当然,我可以重命名ScrambledEqualsCompareAsHtml, ScrambledEqualsComparable为专有名称。但是有两个函数可以解决这个问题。
将旧函数更改为private,以避免外部直接访问。你觉得这个解决方案怎么样?