Domanda

I apologize if the answer is obvious, but Google didn't turn up an answer (possibly because I may not be using the ideal phrasing). I'm trying to overload a LINQ method signature I've created, for user with multiple classes; each signature requires its own logic. I have the following:

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)));
        }
    }
}

Now, when I try to add the following to the MyExtension class, it fails:

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)));
    }
}

This breaks everything, even though the method signature should be different. I tried adding the new method to its own class with no success. How can I overload a method like this?

Edit: The error I'm getting is this -

'System.Linq.IQueryable' does not contain a definition for 'IsReadableBy' and no extension method 'IsReadableBy' accepting a first argument of type 'System.Linq.IQueryable' could be found (are you missing a using directive or an assembly reference?)

The type arguments for method 'Extensions.ModelExtensions.IsReadableBy(System.Linq.IQueryable, Data.Entities.User)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

È stato utile?

Soluzione 2

If you already know the type, why do you need to have generic methods? Simply use the following method signature and it should work for you.

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

Altri suggerimenti

You can't overload methods by constraints only. The method signature (name & parameters) has to be different, and constraints are not part of the method signature.

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

This works. I am not sure what your error is, but I get 2 and 1 on the console.

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;
        }
    }
}

But, if I replace the signatures to use the T -> IsReadableBy<T>(this IEnumerable<T> query), then you get Member with the same signature is already declared. In that case, as agentnega's response is more appropriate....constraints are not part of the signature.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top