Kaihyo
Kaihyo
CC#
Created by Kaihyo on 2/6/2025 in #help
Creating a delegate that accept a ref from a struct method
Hi ! I am working within Unity but this is a C# question. I am trying to implement attributes that alter the appearance of fields in the inspector depending on a condition passed as string. The condition may be a field, a property or a method, which MemberInfo is fetched through reflection. My previous was working in most scenarios except for the case where the attribute is applied on struct's member (which makes sense since struct are not supposed to be mutable). Since my end users may do some shenanigans with struct, I searched a solution and found this post : https://stackoverflow.com/a/1212396 So I tried to adapt it to my needs but I get this error :
ArgumentException: method arguments are incompatible
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure, System.Boolean allowClosed) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
ArgumentException: method arguments are incompatible
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, System.Boolean throwOnBindFailure, System.Boolean allowClosed) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
Since the post is pretty old, my question is: is the answer from the post still valid ? Here is my implementation :
private delegate TResult RefFunc<TArg, TResult>(ref TArg arg);

private static bool TryGetDelegate<T>(string memberName, out RefFunc<T, bool> @delegate)
{
System.Type typeOfT = typeof(T);
MethodInfo method = typeOfT.GetMethod(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new System.Type[] { }, null);
if (method == null)
{
@delegate = null;
return false;
}

@delegate = (RefFunc<T, bool>)System.Delegate.CreateDelegate(typeof(RefFunc<T, bool>), null, method); // The error occures here
return true;
}
private delegate TResult RefFunc<TArg, TResult>(ref TArg arg);

private static bool TryGetDelegate<T>(string memberName, out RefFunc<T, bool> @delegate)
{
System.Type typeOfT = typeof(T);
MethodInfo method = typeOfT.GetMethod(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new System.Type[] { }, null);
if (method == null)
{
@delegate = null;
return false;
}

@delegate = (RefFunc<T, bool>)System.Delegate.CreateDelegate(typeof(RefFunc<T, bool>), null, method); // The error occures here
return true;
}
And the current attribute setup:
public class TestClass : UnityEngine.MonoBehaviour
{
[ShowIf(nameof(ShowIf))]
public UnityEngine.Object TestUnityObject;

private bool ShowIf()
{
return this.ShowGroup;
}
}
public class TestClass : UnityEngine.MonoBehaviour
{
[ShowIf(nameof(ShowIf))]
public UnityEngine.Object TestUnityObject;

private bool ShowIf()
{
return this.ShowGroup;
}
}
23 replies
CC#
Created by Kaihyo on 10/23/2023 in #help
❔ Building a delegate with a Type and a MethodInfo keeps throwing ArgumentException
Hi ! I'm trying to build a delegate from a Type and a MethodInfo. The type correspond to the method 1st argument's type. I have the following code :
public System.Delegate CreateRemoveMethod(System.Type elementType, System.Reflection.MethodInfo methodInfo)
{
if (methodInfo == null)
{
return null;
}

System.Reflection.ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != 1 && parameters[0].ParameterType != elementType)
{
return null;
}

var action = typeof(System.Action<>).MakeGenericType(elementType);
return methodInfo.CreateDelegate(action);
}
public System.Delegate CreateRemoveMethod(System.Type elementType, System.Reflection.MethodInfo methodInfo)
{
if (methodInfo == null)
{
return null;
}

System.Reflection.ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != 1 && parameters[0].ParameterType != elementType)
{
return null;
}

var action = typeof(System.Action<>).MakeGenericType(elementType);
return methodInfo.CreateDelegate(action);
}
Unfortunately, the function throws an exception every time I call it, saying method arguments are incompatible. The signature of the method I'm using to test it is the following one : void LogInConsole(BaseClass item). I'm calling CreateRemoveMethod like this : CreateRemoveMethod(typeof(BaseClass), methodInfo), with methodInfo corresponding LogInConsole that I gathered through reflection. Would you have any insight on what I'm doing wrong here ? 🙂
22 replies