首先,我很抱歉因为我的愚蠢问题。但我希望有人可以帮我解决这个问题。
我有一个Enum,我想添加新的魔术属性,如下所述:
public enum FunctionType
{
[CallMethod(ExecuteFunction.DOPLUS)] //How to implement CallMethod magic attribute
PLUS,
[CallMethod(ExecuteFunction.DOMINUS)]
MINUS,
[CallMethod(ExecuteFunction.DOMULTIPLY)]
MULTIPLY,
[CallMethod(ExecuteFunction.DODIVIDE)]
DIVIDE
}
我的类有一个像这样的FunctionType属性:
public class Function
{
private FunctionType _functionType;
public List<object> Params
{ get; set; }
public FunctionType FunctionType
{
get { return _functionType; }
set { _functionType = value; }
}
public string Execute()
{
return SomeMagicMethod(this.FunctionType); //How to implement this method to return my result as expected
}
}
最后,我的compute类有一些函数返回结果:
public static class ExecuteFunction
{
public static string DOPLUS(int a, int b)
{
return (a + b).ToString();
}
public static string DOMINUS(int a, int b)
{
return (a - b).ToString();
}
public static string DOMULTIPLY(int a, int b)
{
return (a * b).ToString();
}
public static string DODIVIDE(int a, int b)
{
return (a / b).ToString();
}
}
我的愚蠢问题是:我如何在enum和SomeMagicMethod中实现CallMethodAttribute来运行指定的方法而不使用switch case正常?
答案 0 :(得分:3)
您不能在编写时对属性中的方法进行引用(它不是编译时)。
您的方法是错误的 - 您应该使用引用相应枚举的属性来修饰方法,如下所示:
public static class ExecuteFunction
{
[CallMethod(FunctionType.PLUS)]
public static string DOPLUS(int a, int b)
{
return (a + b).ToString();
}
[CallMethod(FunctionType.MINUS)]
public static string DOMINUS(int a, int b)
{
return (a - b).ToString();
}
[CallMethod(FunctionType.MULTIPLY)]
public static string DOMULTIPLY(int a, int b)
{
return (a * b).ToString();
}
[CallMethod(FunctionType.DIVIDE)]
public static string DODIVIDE(int a, int b)
{
return (a / b).ToString();
}
}
属性代码:
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class CallMethodAttribute : Attribute
{
private readonly FunctionType mFunctionType;
public CallMethodAttribute(FunctionType functionType)
{
mFunctionType = functionType;
}
public FunctionType FunctionType
{
get { return mFunctionType; }
}
}
然后使用反射检测给定枚举值类型的相应方法并调用它:
public class YourMagicClass
{
private static readonly Dictionary<FunctionType, MethodInfo> FunctionTypeToMethod =
typeof (ExecuteFunction).
GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(x => x.IsDefined(typeof (CallMethodAttribute)))
.Select(x => new
{
Method = x,
FunctionType = x.GetCustomAttribute<CallMethodAttribute>().FunctionType
})
.ToDictionary(x => x.FunctionType, x => x.Method);
public static string SomeMagicMethod(FunctionType functionType, int a, int b)
{
MethodInfo method;
if (!FunctionTypeToMethod.TryGetValue(functionType, out method))
{
throw new ArgumentException("Could not find a handler for the given function type", "functionType");
}
else
{
string result = (string)method.Invoke(null, new object[] { a, b });
return result;
}
}
}
当然,可以进行优化,例如使用Delegate.CreateDelegate缓存已编译的委托。
答案 1 :(得分:2)
如果您准备用映射字典替换属性:
public class Function
{
private static readonly IDictionary<FunctionType, Func<int, int, string>> functionMappings =
new Dictionary<FunctionType, Func<int, int, string>>
{
{ FunctionType.PLUS, ExecuteFunction.DOPLUS },
{ FunctionType.MINUS, ExecuteFunction.DOMINUS },
{ FunctionType.MULTIPLY, ExecuteFunction.DOMULTIPLY },
{ FunctionType.DIVIDE, ExecuteFunction.DODIVIDE },
};
public string Execute()
{
return functionMappings[_functionType]((int)Params[0], (int)Params[1]);
}
}