【问题标题】:Linq to SQL Extension Method: Method overloading, errorLinq to SQL 扩展方法:方法重载,错误
【发布时间】:2014-02-13 03:49:04
【问题描述】:

如果答案很明显,我深表歉意,但 Google 没有给出答案(可能是因为我可能没有使用理想的措辞)。我正在尝试为具有多个类的用户重载我创建的 LINQ 方法签名;每个签名都需要自己的逻辑。我有以下内容:

public static class myExtension // TODO: Rename.
{
    public static IQueryable<TypeA> IsReadableBy<T>(this IQueryable<TypeA> query, User user)
        where T : TypeA
    {
        if (user.foo("argument")) {
            return query;
        } else if (!user.bar("argument2")) {
            return query.Where(q => q.Collection1.Count == 0 && q.Collection2.Count == 0);
        } else {
            return query.Where(q => q.Collection1.Any(x => x.User.Id == user.Id)
                || q.Collection2.Any(x => x.Group.HasUser(user)));
        }
    }
}

现在,当我尝试将以下内容添加到 MyExtension 类时,它会失败:

public static IQueryable<TypeB> IsReadableBy<T>(this IQueryable<TypeB> query, User user)
    where T : TypeB
{
    if (user.foo("argument") || user.bar("argument2"))
    {
        return query;
    }
    else 
    {
        return query.Where(q => q.Collection1.Any(x => x.User.Id == user.Id)
            || q.Collection2.Any(x => x.Group.Users.Any(u => u.User.Id == user.Id)));
    }
}

这会破坏一切,即使方法签名应该不同。我尝试将新方法添加到它自己的类中,但没有成功。如何重载这样的方法?

编辑:我得到的错误是这个 -

'System.Linq.IQueryable' 没有 包含“IsReadableBy”的定义并且没有扩展方法 'IsReadableBy' 接受类型的第一个参数 'System.Linq.IQueryable' 可能是 找到(您是否缺少 using 指令或程序集引用?)

方法的类型参数 'Extensions.ModelExtensions.IsReadableBy(System.Linq.IQueryable, Data.Entities.User)' 不能从 用法。尝试指定类型参数 明确的。

【问题讨论】:

  • 你得到什么错误?
  • 如果你已经知道类型,为什么还需要泛型方法呢? public static IQueryable&lt;TypeB&gt; IsReadable(this IQueryable&lt;TypeB&gt; query, User user) 会为你工作吗?
  • 我想没有人注意到这里有一个 TaskA 一个 TypeA 类...(对于 TaskB 和 TypeB)
  • @thepirat000 这是一个错误,我已经在更正中进行了编辑。
  • @wdosanjos 这确实有效 - 我删除了泛型,它编译并且似乎有效。

标签: c# linq linq-to-sql overloading extension-methods


【解决方案1】:

您不能仅通过约束来重载方法。方法签名(名称和参数)必须不同,并且约束不是方法签名的一部分。

Eric Lippert's blog: Constraints are not part of the signature

【讨论】:

    【解决方案2】:

    如果你已经知道类型,为什么还需要泛型方法?只需使用以下方法签名,它应该适合您。

    public static IQueryable<TypeB> IsReadable(this IQueryable<TypeB> query, User user)
    

    【讨论】:

      【解决方案3】:

      这行得通。我不确定你的错误是什么,但我在控制台上得到 2 和 1。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Windows;
      
      namespace WpfApplication7
      {
          /// <summary>
          /// Interaction logic for MainWindow.xaml
          /// </summary>
          public partial class MainWindow : Window
          {
              public MainWindow()
              {
                  InitializeComponent();
                  Class1.foo();
              }
          }
      
          public class Class1
          {
              public static void foo()
              {
                  new List<Class2>().IsReadableBy<Class2>();
                  new List<Class1>().IsReadableBy<Class1>();
              }
          }
          public class Class2
          {
      
          }
      
          public static class myExtension // TODO: Rename.
          {
              public static IQueryable<Class1> IsReadableBy<T>(this IEnumerable<Class1> query)
                  where T : Class1
              {
                  Console.WriteLine("1");
                  return null;
              }
      
              public static IQueryable<Class2> IsReadableBy<T>(this IEnumerable<Class2> query)
              where T : Class2
              {
                  Console.WriteLine("2");
                  return null;
              }
          }
      }
      

      但是,如果我将签名替换为使用T -&gt; IsReadableBy&lt;T&gt;(this IEnumerable&lt;T&gt; query),那么您将得到Member with the same signature is already declared。在这种情况下,由于 agentnega 的响应更合适....约束不是签名的一部分。

      【讨论】:

      • 注意问题中有TaskATypeATaskBTypeB)
      猜你喜欢
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多