C
C#ā€¢2y ago
thieved

duplicate methods from .GetMethods()

public ElfinCommand[] ReadCommands()
{
List<ElfinCommand> commands = new List<ElfinCommand>();

var progGroupClasses = GetTypesWithAttribute<ElfinGroupAttribute>();

foreach (Type type in progGroupClasses)
{
MethodInfo[] methods = type.GetMethods().Skip(4).ToArray();
public ElfinCommand[] ReadCommands()
{
List<ElfinCommand> commands = new List<ElfinCommand>();

var progGroupClasses = GetTypesWithAttribute<ElfinGroupAttribute>();

foreach (Type type in progGroupClasses)
{
MethodInfo[] methods = type.GetMethods().Skip(4).ToArray();
so above is my code for getting all classes with the group attribute, and then getting their methods (these methods represent commands). as you can see, though, i have to do .Skip(4) because one of the commands is getting duplicated 4 more times. what could be the cause of this? none of the other methods do this.
public IEnumerable<Type> GetTypesWithAttribute<T>() where T : Attribute
{
foreach (Type type in typeof(Program).Assembly.GetTypes())
{
if (type.GetCustomAttributes(typeof(T), true).Length > 0)
{
yield return type;
}
}
}
public IEnumerable<Type> GetTypesWithAttribute<T>() where T : Attribute
{
foreach (Type type in typeof(Program).Assembly.GetTypes())
{
if (type.GetCustomAttributes(typeof(T), true).Length > 0)
{
yield return type;
}
}
}
here's the method i use to grab groups classes.
49 Replies
thieved
thievedā€¢2y ago
by the way, the groups don't duplicate either
using Elfin.Attributes;
using DSharpPlus.Entities;

namespace Elfin.Commands
{
[ElfinGroup("info")]
public class ElfinInfoCommandGroup
{
[ElfinCommand("helloworld")]
[ElfinAliases(new string[] { "hworld" })]
public async Task HelloWorld(DiscordMessage message, string[] args)
{
Console.WriteLine(message.ToString(), new object[]{args});
await message.RespondAsync("Hello, world!");
}

[ElfinCommand("userinfo")]
[ElfinAliases(new string[] { "uinfo" })]
public async Task UserInfo(DiscordMessage message, string[] args)
{
Console.WriteLine(message.ToString(), new object[]{args});
await message.RespondAsync("some info here idk!");
}
}
}
using Elfin.Attributes;
using DSharpPlus.Entities;

namespace Elfin.Commands
{
[ElfinGroup("info")]
public class ElfinInfoCommandGroup
{
[ElfinCommand("helloworld")]
[ElfinAliases(new string[] { "hworld" })]
public async Task HelloWorld(DiscordMessage message, string[] args)
{
Console.WriteLine(message.ToString(), new object[]{args});
await message.RespondAsync("Hello, world!");
}

[ElfinCommand("userinfo")]
[ElfinAliases(new string[] { "uinfo" })]
public async Task UserInfo(DiscordMessage message, string[] args)
{
Console.WriteLine(message.ToString(), new object[]{args});
await message.RespondAsync("some info here idk!");
}
}
}
here's the code for my commands that i'm trying to work on the UserInfo command does not duplicate, just the HelloWorld oh hey extension thinker ive grown a lot at C# since we last talked lol
Thinker
Thinkerā€¢2y ago
Check what the GetMethods() actually returns
thieved
thievedā€¢2y ago
kk
Thinker
Thinkerā€¢2y ago
There might be some things you wouldn't expect If it's the exact same method repeated four times then that would indeed be very weird
thieved
thievedā€¢2y ago
well how i know its the exact same 4 is because if you .ToString() each method you can see the parameters and theyre all the exact same, DiscordMessage message, string[] args OH SO NOW IT DOESNT WANNA PRINT THEM šŸ™„ thats so weird cuz yesterday my assembly was returning those values but now when i do this
foreach (MethodInfo tMethod in type.GetMethods()) {
Console.WriteLine(tMethod);
}
foreach (MethodInfo tMethod in type.GetMethods()) {
Console.WriteLine(tMethod);
}
it prints just 2 whic his the normal amount
thieved
thievedā€¢2y ago
Thinker
Thinkerā€¢2y ago
hmm
thieved
thievedā€¢2y ago
okay so now with the code i have it does this.
thieved
thievedā€¢2y ago
thieved
thievedā€¢2y ago
why does it print different values each time.. like the number of values i mean look
foreach (MethodInfo tMethod in type.GetMethods()) {
Console.WriteLine(tMethod);
}

MethodInfo[] methods = type.GetMethods();

Console.WriteLine(methods.Length);
foreach (MethodInfo tMethod in type.GetMethods()) {
Console.WriteLine(tMethod);
}

MethodInfo[] methods = type.GetMethods();

Console.WriteLine(methods.Length);
so in the loop it prints 2 like normal but when i apply it to that variable and print the length and the method list it gives me 6 instead of 2 just the HelloWorld one is being duplicated.. but also on the second line it returns actions rather than tasks ??
thieved
thievedā€¢2y ago
thieved
thievedā€¢2y ago
wait
Thinker
Thinkerā€¢2y ago
what are you actually printing in the second
thieved
thievedā€¢2y ago
i know the issue sorta
Thinker
Thinkerā€¢2y ago
that looks like you're printing a method
thieved
thievedā€¢2y ago
oh yea i forgot to remove that its just the response function for the cmd
Thinker
Thinkerā€¢2y ago
yeah so you're printing that
thieved
thievedā€¢2y ago
Thinker
Thinkerā€¢2y ago
that looks fine
thieved
thievedā€¢2y ago
oh im slow HELP I JUST REALIZED šŸ˜­ it was the way i was printing gthings that tripped me up šŸ˜­
Thinker
Thinkerā€¢2y ago
catsip
thieved
thievedā€¢2y ago
um i have a question though another one let me test something first hold on okay so,
thieved
thievedā€¢2y ago
thieved
thievedā€¢2y ago
this prints as expected right but
ElfinCommand newCommand = new()
{
Name = commandName,
Aliases = aliases
};

newCommand.Respond = (DiscordMessage message, string[] args) =>
{
Console.WriteLine(111111);
typeMethod.Invoke(newCommand, new object[] { message, args });
};

commands.Add(newCommand);
ElfinCommand newCommand = new()
{
Name = commandName,
Aliases = aliases
};

newCommand.Respond = (DiscordMessage message, string[] args) =>
{
Console.WriteLine(111111);
typeMethod.Invoke(newCommand, new object[] { message, args });
};

commands.Add(newCommand);
what im trying to do is apply a custom response property that is basically the command's method call the 11111 prints but the method does not invoke im not sure what i did wrong no error is thrown.. but it doesnt print anything in the command's method
Thinker
Thinkerā€¢2y ago
btw you know D#+ has a commands module, right
thieved
thievedā€¢2y ago
i know i prefer to do things on my own for max customizability and you get my point i hope but yea idk whats wrong the docs on .Invoke r confusing but i know that i need to pass the parent class but i dont know if im passing the rest right
foreach (MethodInfo typeMethod in methods)
{
string commandName = "";
string[] aliases = { };
IEnumerable<Attribute> attributes = typeMethod.GetCustomAttributes();

foreach (Attribute attr in attributes)
{
string? attrName = attr.ToString();

if (attrName.Contains("Command"))
{
commandName = ((ElfinCommandAttribute)attr).Name;
}
else if (attrName.Contains("Aliases"))
{
aliases = ((ElfinAliasesAttribute)attr).Aliases;
}
}

ElfinCommand newCommand = new()
{
Name = commandName,
Aliases = aliases
};

newCommand.Respond = (DiscordMessage message, string[] args) =>
{
Console.WriteLine(111111);
typeMethod.Invoke(newCommand, new object[] { message, args });
};

commands.Add(newCommand);
}
}
foreach (MethodInfo typeMethod in methods)
{
string commandName = "";
string[] aliases = { };
IEnumerable<Attribute> attributes = typeMethod.GetCustomAttributes();

foreach (Attribute attr in attributes)
{
string? attrName = attr.ToString();

if (attrName.Contains("Command"))
{
commandName = ((ElfinCommandAttribute)attr).Name;
}
else if (attrName.Contains("Aliases"))
{
aliases = ((ElfinAliasesAttribute)attr).Aliases;
}
}

ElfinCommand newCommand = new()
{
Name = commandName,
Aliases = aliases
};

newCommand.Respond = (DiscordMessage message, string[] args) =>
{
Console.WriteLine(111111);
typeMethod.Invoke(newCommand, new object[] { message, args });
};

commands.Add(newCommand);
}
}
heres the full code for that (just for context)
Thinker
Thinkerā€¢2y ago
!docs MethodInfo.Invoke
MODiX
MODiXā€¢2y ago
Could not find documentation for your requested term.
thieved
thievedā€¢2y ago
the web docs are a bit confusing šŸ˜­
thieved
thievedā€¢2y ago
Thinker
Thinkerā€¢2y ago
The first argument to Invoke is the object to invoke the method on (or null if the method is static). Here you're passing newCommand as that object.
thieved
thievedā€¢2y ago
yes
Thinker
Thinkerā€¢2y ago
And newCommand is a ElfinCommand, which probably doesn't have the target method, right
thieved
thievedā€¢2y ago
target method? oh
thieved
thievedā€¢2y ago
thieved
thievedā€¢2y ago
it seems to work when you change the commands to static methods i wonder why šŸ¤”
MODiX
MODiXā€¢2y ago
thinker227#5176
REPL Result: Failure
class A
{
public void Foo() => Console.WriteLine("foo");
}
class B {}

typeof(A).GetMethod("Foo").Invoke(new B(), Array.Empty<object>())
class A
{
public void Foo() => Console.WriteLine("foo");
}
class B {}

typeof(A).GetMethod("Foo").Invoke(new B(), Array.Empty<object>())
Exception: TargetException
- Object does not match target type.
- Object does not match target type.
Compile: 655.940ms | Execution: 104.722ms | React with āŒ to remove this embed.
Thinker
Thinkerā€¢2y ago
yeah because the obj argument is ignored if the method is static otherwise this will happen
thieved
thievedā€¢2y ago
hmm well i mean there seems no reason for the object to be accounted for its simply a holder class lol so that sorta makes sense
Thinker
Thinkerā€¢2y ago
well, if it's an instance method, then you need an object to invoke the instance method on if it's static, then you don't need an object to invoke it on
thieved
thievedā€¢2y ago
what exactly is an instance method?
Thinker
Thinkerā€¢2y ago
a method which isn't static
thieved
thievedā€¢2y ago
ah so any methods that are non-static are instance methods?
Thinker
Thinkerā€¢2y ago
class Class
{
public void InstanceMethod() {}
public static void StaticMethod() {}
}
class Class
{
public void InstanceMethod() {}
public static void StaticMethod() {}
}
thieved
thievedā€¢2y ago
okay i thought so something that is for a constructed class gotcha umm could you help me with one more thing?
Thinker
Thinkerā€¢2y ago
sure
thieved
thievedā€¢2y ago
its not a problem exactly its i just want to be criticized on my code because it seems messy and odd so i want to know what i can do better
Thinker
Thinkerā€¢2y ago
post in #code-review
thieved
thievedā€¢2y ago
kk ty