IList传递给 IEnumerable 参数

本文关键字:IEnumerable 参数 string IList | 更新日期: 2023-09-27 18:35:40

今天早上我的大脑根本无法工作,所以我希望有人能为我解决这个问题。

我有一个小的助手方法,可以检查 IEnumerable 是否为空或没有项目。

public static class ParameterGuard
{
    public static void ThrowIfNullOrEmtpy<T>(T enumerable, string argName) where T : IEnumerable
    {
        if (enumerable == null)
            throw new ArgumentNullException(argName);
        if (enumerable.HasCountOf(0))
            throw new ArgumentException(Resources.ExceptionEnumerableEmpty, argName);
    }
    public static void ThrowIfNullOrEmpty(string arg, string argName)
    {
        if (arg == null) 
            throw new ArgumentNullException(argName);
        if (arg.Length == 0) 
            throw new ArgumentException(Resources.ExceptionStringEmpty, argName);
    }
}

我还有一个用于发送电子邮件的小数据结构

public class EmailOptions
{
    public string Server { get; set; }
    public int Port { get; set; }
    public string From { get; set; }
    public List<string> To { get; set; }
    public List<string> Cc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public bool IsHtml { get; set; }
}

当我尝试使用 ThrowIfNullOrEmpty 方法验证 To 属性时,出现异常。

  private MailMessage CreateEmail(EmailOptions options)
  {
        ParameterGuard.ThrowIfNullOrEmpty(options.To, "To");
        ...
  }

例外

The best overloaded method match for 
ParameterGuard.ThrowIfNullOrEmpty(string, string)' has some invalid arguments

我本以为,当 IList<> 类实现 IEnumerable 时,这会起作用。

我希望有人为我澄清这一点。

IList<string>传递给 IEnumerable 参数

我已经尝试了代码,如果这两种方法确实都是重载,则(正确)使用通用版本。

在粘贴的代码中,第一个函数称为 ThrowIfNullOrEmtpy ,而不是 ThrowIfNullOrEmpty ,因此它是一个简单的拼写错误。


这个 LINQPad 代码:

void Main()
{
  CreateEmail(new EmailOptions());
}
private void CreateEmail(EmailOptions options)
{
  ParameterGuard.ThrowIfNullOrEmpty(options.To, "To");
}
public static class ParameterGuard
{
      public static void ThrowIfNullOrEmpty<T>(T enumerable, string argName) 
        where T : IEnumerable
      {
          Console.Write("Generic Version");
      }
      public static void ThrowIfNullOrEmpty(string arg, string argName)
      {
          Console.Write("String Version");
      }
}
public class EmailOptions
{
    public List<string> To { get; set; }
}

返回"通用版本"

不是像你使用的那样使用通用方法,而是使用普通方法:

public static void ThrowIfNullOrEmtpy(IEnumerable enumerable, string argName);

通用不是必需的。

其次。这些方法具有不同的名称。这可能只是一个错字:

ThrowIfNullOrEmtpyThrowIfNullOrEmpty

你为什么不试试这个:

public static void ThrowIfNullOrEmpty<T>(IEnumerable<T> enumerable, string argName)
{
    ...
}

如上所述,您将在第一个方法名称中出错。

string也实现了IEnumerable,你只能使用一种方法:

public static class ParameterGuard
{
    public static void ThrowIfNullOrEmpty<T>(IEnumerable<T> enumerable, string argName)
    {
        if (enumerable == null)
            throw new ArgumentNullException(argName);
        if (!enumerable.Any())
            throw new ArgumentException();
    }
}
public class Program
{
    static void Main(string[] args)
    {
        List<string> list = new List<string>();
        list.Add("test");
        ParameterGuard.ThrowIfNullOrEmpty(list, "list");
        ParameterGuard.ThrowIfNullOrEmpty("string", "str");
    }
}

更改方法签名,如下所示:

public static class ParameterGuard
{
    public static void ThrowIfNullOrEmpty(IEnumerable enumerable, string argName)
    {
    }
    public static void ThrowIfNullOrEmpty(string arg, string argName)
    {
    }
}

您的两种方法都有一个小错别字,这可能是导致混乱的原因。这样,您应该使用可枚举对象调用该方法。