是否可以扩展 List<T> 但仅适用于 T = 精确类型?
Is it possible to extend List<T> but only for T = exact type?
我正在尝试扩展 类 并成功地扩展了 List<T>
是为了好玩:
public static void SomeCustomSort<T>(this List<T> list, string item)
{
if (typeof(T) != typeof(string) || list.Count == 0)
return;
// doStuff();
}
我想知道是否有更聪明的方法来仅针对 List<string>
扩展 List<T>
,这样我的扩展方法就不会被列出或无法被任何其他类型访问 T
只需使您的方法非泛型即可:
public static void SomeCustomSort(this List<string> list, string item)
并指定它应该使用的确切类型
注意:使用 void 方法,即使您想将扩展方法参数限制为某些类型集(例如,某些接口的所有实现者或某些非密封 class 和 classes 派生自它)我不建议使用带有参数约束的泛型方法:
public static void SomeCustomSort<T>(this List<T> animals)
where T: IAnimal
为什么?因为它会使您的代码过于复杂。非泛型方法比泛型方法更容易理解。没有约束的泛型方法比有约束的泛型方法更容易理解。您应该从易于理解的最简单的解决方案开始。哪个听起来更自然?
- "It sorts list of animals"
- "It sorts list of items of any type"
- "It sorts list of items of any type which is animal"
什么时候使用泛型类型约束?当您从您的方法中 return 项并且您不想丢失有关列表项的确切类型的信息时。考虑通过一些权重过滤器
returns 动物的方法
public static IEnumerable<IAnimal> WhereWeightBelow(this List<IAnimal> animals, int weight)
如果您将狗的列表传递给此方法,您将失去方法输出中所有特定于狗的信息的智能感知。
dogs.WhereWeightBelow(10).Where(d => d. /* oops only IAnimal members here */)
返回通用类型将为您保留所有狗的信息。
只需指定 T
而不是将其设为通用方法。
public static void SomeCustomSort(this List<string> list, string item)
只需在您的扩展方法中准确定义字符串类型
public static void SomeCustomSort(this List<string> list, string item)
{
// doStuff();
}
另一个尚未提及的替代方案:
public static void SomeCustomSort<T>(this List<T> list, string item)
where T: YourSpecificType
这允许您指定不止一种类型,例如:
public static void SomeCustomSort<T>(this List<T> list, string item)
where T: ISortable, ICustomInterface
您也可以使用这样的约束(在此示例中,T 必须是 Project 类型):
public static void SomeCustomSort<T>(this List<T> list, string item)
where T : Project
{
}
我将在下面的示例中向您展示如何轻松扩展通用列表。
我将列表扩展为 return 来自列表本身的随机数据。
我们有一个class例如:
public class ExampleClass
{
public string Name { get; set; }
}
我们现在已经用某种方法列出了这些 classes:
var exampleList = new List<ExampleClass>()
{
new ExampleClass()
{
Name = "Class1"
},
new ExampleClass()
{
Name = "Class2"
},
new ExampleClass()
{
Name = "Class3"
}
};
var randomList = exampleList.Random(2);
以下是return从列表
中随机对象的简单实现
public static class ListExtensions
{
public static IList<T> Random<T>(this IList<T> list, int numberOfResult) where T : class
{
if (list == null) throw new ArgumentNullException(nameof(list));
if (numberOfResult <= 0 || numberOfResult > list.Count) throw new ArgumentOutOfRangeException(nameof(numberOfResult));
var random = new Random();
var randomList = new List<T>();
var randomNumbers = new List<int>();
while (randomList.Count < numberOfResult)
{
var index = random.Next(list.Count);
if (randomNumbers.IndexOf(index) < 0)
{
randomNumbers.Add(index);
randomList.Add(list[index]);
}
}
return randomList;
}
}
我正在尝试扩展 类 并成功地扩展了 List<T>
是为了好玩:
public static void SomeCustomSort<T>(this List<T> list, string item)
{
if (typeof(T) != typeof(string) || list.Count == 0)
return;
// doStuff();
}
我想知道是否有更聪明的方法来仅针对 List<string>
扩展 List<T>
,这样我的扩展方法就不会被列出或无法被任何其他类型访问 T
只需使您的方法非泛型即可:
public static void SomeCustomSort(this List<string> list, string item)
并指定它应该使用的确切类型
注意:使用 void 方法,即使您想将扩展方法参数限制为某些类型集(例如,某些接口的所有实现者或某些非密封 class 和 classes 派生自它)我不建议使用带有参数约束的泛型方法:
public static void SomeCustomSort<T>(this List<T> animals)
where T: IAnimal
为什么?因为它会使您的代码过于复杂。非泛型方法比泛型方法更容易理解。没有约束的泛型方法比有约束的泛型方法更容易理解。您应该从易于理解的最简单的解决方案开始。哪个听起来更自然?
- "It sorts list of animals"
- "It sorts list of items of any type"
- "It sorts list of items of any type which is animal"
什么时候使用泛型类型约束?当您从您的方法中 return 项并且您不想丢失有关列表项的确切类型的信息时。考虑通过一些权重过滤器
returns 动物的方法public static IEnumerable<IAnimal> WhereWeightBelow(this List<IAnimal> animals, int weight)
如果您将狗的列表传递给此方法,您将失去方法输出中所有特定于狗的信息的智能感知。
dogs.WhereWeightBelow(10).Where(d => d. /* oops only IAnimal members here */)
返回通用类型将为您保留所有狗的信息。
只需指定 T
而不是将其设为通用方法。
public static void SomeCustomSort(this List<string> list, string item)
只需在您的扩展方法中准确定义字符串类型
public static void SomeCustomSort(this List<string> list, string item)
{
// doStuff();
}
另一个尚未提及的替代方案:
public static void SomeCustomSort<T>(this List<T> list, string item)
where T: YourSpecificType
这允许您指定不止一种类型,例如:
public static void SomeCustomSort<T>(this List<T> list, string item)
where T: ISortable, ICustomInterface
您也可以使用这样的约束(在此示例中,T 必须是 Project 类型):
public static void SomeCustomSort<T>(this List<T> list, string item)
where T : Project
{
}
我将在下面的示例中向您展示如何轻松扩展通用列表。 我将列表扩展为 return 来自列表本身的随机数据。
我们有一个class例如:
public class ExampleClass
{
public string Name { get; set; }
}
我们现在已经用某种方法列出了这些 classes:
var exampleList = new List<ExampleClass>()
{
new ExampleClass()
{
Name = "Class1"
},
new ExampleClass()
{
Name = "Class2"
},
new ExampleClass()
{
Name = "Class3"
}
};
var randomList = exampleList.Random(2);
以下是return从列表
中随机对象的简单实现public static class ListExtensions
{
public static IList<T> Random<T>(this IList<T> list, int numberOfResult) where T : class
{
if (list == null) throw new ArgumentNullException(nameof(list));
if (numberOfResult <= 0 || numberOfResult > list.Count) throw new ArgumentOutOfRangeException(nameof(numberOfResult));
var random = new Random();
var randomList = new List<T>();
var randomNumbers = new List<int>();
while (randomList.Count < numberOfResult)
{
var index = random.Next(list.Count);
if (randomNumbers.IndexOf(index) < 0)
{
randomNumbers.Add(index);
randomList.Add(list[index]);
}
}
return randomList;
}
}