SelectMany arguments cannot be taken out of use

I have a controller on which there are several actions, some of them may have their own attribute. I want to use linq to select some data in an anonymous type for each action on the controller, for example.

    Controller1
    Action1
    [MyAttribute("Con1Action2)"]
    Action2
    [MyAttribute("Con1Action3")]
    Action3


    Controller2
    Action1
    [MyAttribute("Con2Action2)"]
    Action2
    [MyAttribute("Con2Action3")]
    Action3

I want the following to return:

NameSpace = "someText", Controller = "Controller1", ActionName = "Con1Action2", 
NameSpace = "someText", Controller = "Controller1", ActionName = "Con1Action3",
NameSpace = "someText", Controller = "Controller2", ActionName = "Con2Action2", 
NameSpace = "someText", Controller = "Controller2", ActionName = "Con2Action3"

I struggle with SelectMany for every action:

var controllers= myControllerList
.Where(type =>type.Namespace.StartsWith("X.") &&
    type.GetMethods().Any(m => m.GetCustomAttributes(typeof(MyAttribute)).Any()))
.SelectMany(type =>
{
    var actionNames = type.GetMethods().Where(m => m.GetCustomAttributes(typeof(MyAttribute)).Any()).ToList();

    var actionName = (MyAttribute)actionNames[0].GetCustomAttribute(typeof(MyAttribute));
    return new
    {
        Namespace = GetPath(type.Namespace),
        ActionName= actionName.Name,
        Controller = type.Name.Remove(2);
    };
}).ToList();

I get an error in SelectMany - type arguments for a method ... cannot be taken out of use.

+4
source share
3 answers

"SelectMany IEnumerable ". : https://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.100).aspx

:

return new
{
    Namespace = GetPath(type.Namespace),
    ActionName= actionName.Name,
    Controller = type.Name.Remove(2);
};

.

SelectMany, , colection, :

projects.SelectMany(p => p.Technologies).ToList()

, , , .

, , :

var controllers= myControllerList
.Where(type =>type.Namespace.StartsWith("X.") &&
    type.GetMethods().Any(m => m.GetCustomAttributes(typeof(MyAttribute)).Any()))
.SelectMany(type =>
{
    var actionNames = type.GetMethods().Where(m => m.GetCustomAttributes(typeof(MyAttribute)).Any()).ToList();  

    return actionNames.Select(action => {
        var actionName = (MyAttribute)action.GetCustomAttribute(typeof(MyAttribute));
        return new
        {
             Namespace = GetPath(type.Namespace),
             ActionName= actionName.Name,
             Controller = type.Name.Remove(2);      
        });
    });    
}).ToList();
+1

, - SelectMany. IEnumerable<T> , , Type. Type IEnumerable<T>. , .

SelectMany Select, .

0

, , new {}, selectmany .

, selectmany (, return actionNames.Select(a=> new {...), , . ( , )

Just a suggestion (and with air coding, therefore, it can have syntax errors), but if you request all methods (selectmany), be an attribute for the methodinfo method, then check where it is filled, you only look for the attribute once:

var controllers= myControllerList
.Where(type =>type.Namespace.StartsWith("X."))
.SelectMany(type => type.GetMethods())
.Select(m =>  new {
   Type = m.DeclaringType, 
   Att = m.GetCustomAttribute(typeof(MyAttribute)) as MyAttribute
})
.Where(t=>t.Att!=null)
.Select(t=> new
    {
        Namespace = GetPath(t.Type.Namespace),
        ActionName= t.Att.Name,
        Controller = t.Type.Name.Remove(2);
    }
).ToList();
0
source

Source: https://habr.com/ru/post/1627419/


All Articles