ObservableCollection 和 IEnumerable 的通用方法
Generic method for ObservableCollection and IEnumerable
我有这个功能:
public static double MaxValue(IEnumerable<double> Collection)
{
double max = Collection.First();
foreach (double d in Collection)
if (d > max)
max = d;
return max;
}
如果我定义一个泛型方法:MaxValue<T>(IEnumerable<T> Collection)
我如何确保没有人可以在没有定义 <
>
的自定义类型上使用它?这是一件值得担心的好事吗?
我怎样才能只编写一种同时适用于 IEnumerable
和 ObservableCollection
的方法?
正如其他人在评论中提到的,您正在重新发明轮子;您可以使用 Linq 中的 Max
扩展方法。
If I define a generic method: MaxValue(IEnumerable Collection) how can I assure that no one could use that on a custom type without < > defined? Is this a good thing to be worried of?
您可以添加通用约束以确保类型实现 IComparable<T>
:
public static T MaxValue<T>(IEnumerable<T> collection) where T : IComparable<T>
并使用CompareTo
方法代替比较运算符。
How can I code just one method that works both for IEnumerable and ObservableCollection?
您的方法已经适用于 ObservableCollection<T>
,因为它实现了 IEnumerable<T>
附带说明一下,您当前的实现有一个缺陷:它枚举了两次集合,在惰性 IEnumerable<T>
的情况下,这是一个坏主意,因为枚举它可能会导致数据库调用,或网络请求,或其他任何东西。一般来说,避免多次枚举一个可枚举。
If I define a generic method: MaxValue<T>(IEnumerable<T> Collection)
how can I assure that no one could use that on a custom type without < > defined? Is this a good thing to be worried of?
如果我明白你在说什么,你根本不能使用这里定义的泛型方法。如果你愿意,你需要约束 T
来实现 IComparable<T>
,这样你就可以将它与另一个值进行比较,或者在你的方法中使用 IComparer<T>
(然后就不需要约束了):
public T MaxValue<T>(IEnumerable<T> collection) where T : IComparable<T>
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = element.CompareTo(maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
或
public T MaxValue<T>(IEnumerable<T> collection, IComparer<T> comparer)
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = comparer.Compare(element, maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
How can I code just one method that works both for IEnumerable and
ObservableCollection?
ObservableCollection<T>
实施 IEnumerable<T>
。您可以做的是创建一个应用于任何 IEnumerable<T>
的扩展方法,类似于 LINQ
通过 System.Linq
命名空间工作的方式:
public static class Extensions
{
public static T MaxValue<T>(this IEnumerable<T> collection) where T : IComparable<T>
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = element.CompareTo(maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
public static T MaxValue<T>(this IEnumerable<T> collection, IComparer<T> comparer)
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = comparer.Compare(element, maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
}
If I define a generic method: MaxValue(IEnumerable Collection)
how can I assure that no one could use that on a custom type without <> defined? > Is this a good thing to be worried of?
对于这样的事情,通用约束总是派上用场,因此您可以定义一个接口,即:
public interface IMyInterface
{
public decimal Amount { get; set; }
}
然后写一个方法:
public static decimal MaxValue<T>(IEnumerable<T> myCol) where T : IMyInterface
{
decimal max = myCol.First().Amount;
// then iterate collection to find max value, code ommitted
}
但如前所述,已经有多种方法可以让您使用 linq
执行此操作,因此除非您确实需要这样做,否则请使用现有的方法。
我有这个功能:
public static double MaxValue(IEnumerable<double> Collection)
{
double max = Collection.First();
foreach (double d in Collection)
if (d > max)
max = d;
return max;
}
如果我定义一个泛型方法:
MaxValue<T>(IEnumerable<T> Collection)
我如何确保没有人可以在没有定义<
>
的自定义类型上使用它?这是一件值得担心的好事吗?我怎样才能只编写一种同时适用于
IEnumerable
和ObservableCollection
的方法?
正如其他人在评论中提到的,您正在重新发明轮子;您可以使用 Linq 中的 Max
扩展方法。
If I define a generic method: MaxValue(IEnumerable Collection) how can I assure that no one could use that on a custom type without < > defined? Is this a good thing to be worried of?
您可以添加通用约束以确保类型实现 IComparable<T>
:
public static T MaxValue<T>(IEnumerable<T> collection) where T : IComparable<T>
并使用CompareTo
方法代替比较运算符。
How can I code just one method that works both for IEnumerable and ObservableCollection?
您的方法已经适用于 ObservableCollection<T>
,因为它实现了 IEnumerable<T>
附带说明一下,您当前的实现有一个缺陷:它枚举了两次集合,在惰性 IEnumerable<T>
的情况下,这是一个坏主意,因为枚举它可能会导致数据库调用,或网络请求,或其他任何东西。一般来说,避免多次枚举一个可枚举。
If I define a generic method:
MaxValue<T>(IEnumerable<T> Collection)
how can I assure that no one could use that on a custom type without < > defined? Is this a good thing to be worried of?
如果我明白你在说什么,你根本不能使用这里定义的泛型方法。如果你愿意,你需要约束 T
来实现 IComparable<T>
,这样你就可以将它与另一个值进行比较,或者在你的方法中使用 IComparer<T>
(然后就不需要约束了):
public T MaxValue<T>(IEnumerable<T> collection) where T : IComparable<T>
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = element.CompareTo(maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
或
public T MaxValue<T>(IEnumerable<T> collection, IComparer<T> comparer)
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = comparer.Compare(element, maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
How can I code just one method that works both for IEnumerable and ObservableCollection?
ObservableCollection<T>
实施 IEnumerable<T>
。您可以做的是创建一个应用于任何 IEnumerable<T>
的扩展方法,类似于 LINQ
通过 System.Linq
命名空间工作的方式:
public static class Extensions
{
public static T MaxValue<T>(this IEnumerable<T> collection) where T : IComparable<T>
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = element.CompareTo(maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
public static T MaxValue<T>(this IEnumerable<T> collection, IComparer<T> comparer)
{
T maxValue = default(T);
foreach (var element in collection)
{
var comparsion = comparer.Compare(element, maxValue);
if (comparsion > 0)
maxValue = element;
}
return maxValue;
}
}
If I define a generic method: MaxValue(IEnumerable Collection) how can I assure that no one could use that on a custom type without <> defined? > Is this a good thing to be worried of?
对于这样的事情,通用约束总是派上用场,因此您可以定义一个接口,即:
public interface IMyInterface
{
public decimal Amount { get; set; }
}
然后写一个方法:
public static decimal MaxValue<T>(IEnumerable<T> myCol) where T : IMyInterface
{
decimal max = myCol.First().Amount;
// then iterate collection to find max value, code ommitted
}
但如前所述,已经有多种方法可以让您使用 linq
执行此操作,因此除非您确实需要这样做,否则请使用现有的方法。