是否可以使用常量值来命名函数?

时间:2014-05-11 17:14:22

标签: c# asp.net-mvc-4

我想做点什么

public ActionResult Constants.MethodName()
{
return View();
}

你认为可能吗?

更新: 我想这样,因为我在客户端有一些应用程序的组件调用此方法。所以,如果有一天我想重命名这个方法,那么一切都将被打破。如果我使用常量,我可以毫无问题地重命名它。 示例中的Constants是一个共享库,是项目中具有解决方案所有常量的静态类。

Constants看起来像这样

public static class Constants
{
    public const string MethodName = "MethodName";    
}

在客户端:

            HubConnection connection = new HubConnection(_hubUrl);
            IHubProxy proxy = connection.CreateHubProxy(Constants.MethodName);
            connection.Start().Wait();

3 个答案:

答案 0 :(得分:5)

不,但我认为您可以通过在共享库中实施interface来实现您正在寻找的结果,而不是在该库中引用constant

在客户端和服务器共享的库中:

public interface ISomeService
{
    SomeResult SomeAction();
}

在服务器上:

public SomeService : ApiController, ISomeService
{
    public SomeResult SomeAction() {...}
}

在客户端:

SomeResult someResult = await serviceLayer.Invoke<ISomeService>(s => s.SomeAction());

这样的结构允许您在界面上重命名服务方法,并使用重构工具自动在客户端和服务器代码中重命名。

答案 1 :(得分:2)

这个怎么样:

public class HomeController : Controller
{
    public ActionResult MethodName()
    {
        return View();
    }
}

然后:

Expression<Action<HomeController>> expression = (HomeController c) => c.MethodName();
string actionName = ((MethodCallExpression)expression.Body).Method.Name;

HubConnection connection = new HubConnection(_hubUrl);
IHubProxy proxy = connection.CreateHubProxy(actionName);
connection.Start().Wait();

现在你可以重构 - &gt;根据需要重命名你的动作而不会破坏任何东西。代码中没有任何魔术字符串,您不需要任何常量或明显不可能的public ActionResult Constants.MethodName() C#语法。

如果您的操作采用参数,则只需在表达式调用中传递default(ParameterType)值,因为未调用操作且值不重要。

答案 2 :(得分:1)

public static class Constants
{
    public ActionResult ConstantName()
    {
        return View();
    }
}

我认为你的意思是什么?然后你可以通过Constants.ConstantName()...

访问它

如果您在重命名方法后担心与客户端的兼容性,那么这是所有共享库面临的常见问题。

如果您希望稍后重命名该方法,最好的办法是简单地保留旧函数并返回新函数的值,以便使用旧调用方法的人仍然可以获得新方法的返回值。即。

public int Double(int i)
{
    return i * 2;
}

......几个月后......

[Obsolete("Use NewDouble instead.")]
public int Double(int i)
{
    return NewDouble(i);
}

public int NewDouble(int i)
{
    return i << 1;
}

编辑:哦,我想我明白你的意思了。您希望能够将静态名称分配给未在代码中实际反映的函数吗?因此,如果您在客户端中引用一个名为Whatever()的方法并稍后将其名称更改为Whatever2(),则客户端仍然可以引用该方法,因为它的静态名称。

我能想到的唯一方法就是使用Reflection。您可以为每个方法创建一个具有唯一标识符的属性,然后让客户端使用非客户端提供的Dictionary,以检索该方法的MethodInfo对象,然后使用该方法调用该方法。

再次修改:我实现了这个以确定它是否可行,而且似乎已经足够了。

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
sealed class MethodIDAttribute : Attribute
{
    public int ID { get; private set; }

    public MethodIDAttribute(int id)
    { this.ID = id; }
}

public class TestClass
{
    public static Dictionary<int, MethodInfo> MethodIDs = new Dictionary<int, MethodInfo>();

    static TestClass()
    {
        MethodInfo[] mi = typeof(TestClass).GetMethods();
        foreach (MethodInfo info in mi)
        {
            if (info.Name == "ToString" || info.Name == "Equals" || info.Name == "GetHashCode" || info.Name == "GetType")
            { continue; }
            int id = ((MethodIDAttribute)info.GetCustomAttribute(typeof(MethodIDAttribute))).ID;
            MethodIDs.Add(id, info);
        }
    }

    [MethodID(123456)]
    public int Double(int i)
    {
        return i * 2;
    }
}

public static class Constants
{
    public static class TestClass
    {
        public static int Double = 123456;
    }
}

public class ExampleCaller
{
    public int SomeMethod()
    {
        TestClass tc = new TestClass();
        return (int)TestClass.MethodIDs[Constants.TestClass.Double].Invoke(tc, new object[] { 10 });
    }
}

您或许可以简单地创建一个类可以继承的抽象基类,它可以实现MethodIDs Dictionary并填充它们。

这个解决方案虽然很难看......