是否可以扩展 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;
    }
}