C# 可以用常量值命名函数吗?
我想做一些像C# 可以用常量值命名函数吗?,c#,asp.net-mvc-4,C#,Asp.net Mvc 4,我想做一些像 public ActionResult Constants.MethodName() { return View(); } 你认为可能吗 更新: 我之所以喜欢这个方法,是因为我在客户端有一些调用这个方法的应用程序组件。所以,如果有一天我想重命名这个方法,所有的方法都会被破坏。如果我使用一个常量,我可以毫无问题地重命名它。 示例中的常量是一个共享库,它是项目中的一个静态类,包含解决方案的所有常量 常量看起来像这样 public static class Constants {
public ActionResult Constants.MethodName()
{
return View();
}
你认为可能吗
更新:
我之所以喜欢这个方法,是因为我在客户端有一些调用这个方法的应用程序组件。所以,如果有一天我想重命名这个方法,所有的方法都会被破坏。如果我使用一个常量,我可以毫无问题地重命名它。
示例中的常量是一个共享库,它是项目中的一个静态类,包含解决方案的所有常量
常量看起来像这样
public static class Constants
{
public const string MethodName = "MethodName";
}
在客户端:
HubConnection connection = new HubConnection(_hubUrl);
IHubProxy proxy = connection.CreateHubProxy(Constants.MethodName);
connection.Start().Wait();
不,但我认为,通过在共享库中实现接口,而不是引用该库中的常量,可以实现所需的结果 在客户端和服务器共享的库中:
public interface ISomeService
{
SomeResult SomeAction();
}
在服务器上:
public SomeService : ApiController, ISomeService
{
public SomeResult SomeAction() {...}
}
在客户机上:
SomeResult someResult = await serviceLayer.Invoke<ISomeService>(s => s.SomeAction());
这样的结构允许您重命名接口上的服务方法,并使用重构工具在客户机和服务器代码中自动重命名它
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;
}
编辑:哦,我想我明白你的意思了。您希望能够将静态名称分配给代码中实际上没有反映的函数吗?因此,如果您在客户机中引用一个名为whather的方法,并在以后将其名称更改为Whatever2,那么客户机仍然可以引用该方法,因为它是静态名称
我能想到的唯一方法就是使用反射。您可以为每个方法创建一个具有唯一标识符的属性,然后让客户端使用非客户端提供的字典来检索该方法的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字典及其填充
这个解决方案非常难看…这个怎么样:
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();
现在你可以重构->重命名你的动作,而不破坏任何东西。代码中没有任何神奇的字符串,也不需要任何常量或显然不可能的公共ActionResult constants.MethodName C语法
如果您的操作采用了参数,您只需在表达式调用中传递defaultParameterType值,因为该操作未被调用,并且这些值无关紧要。简而言之:不,我不知道。我不明白。常量是一个类的名称吗?你为什么需要它?好吧,如果你发出IL,你当然可以这样做。这是完全错误的方法。为什么要更改操作的方法名称?这将改变您的所有URL。即使如此,使用常数如何解决问题?请详细说明你的问题。@AntP:我详细说明了一下。这种方法需要做一些额外的工作,并对OP中的一些小细节进行一些修改,但至少有理由认为它可以做到。我非常喜欢这种方法。但是使用这种方法,我需要客户端应用程序具有对web服务器端的引用?这样可以吗?一种可能是将操作抽象到控制器将实现的接口中。然后将此接口放入第三个程序集中,该程序集将在服务器和客户端之间共享。此接口将表示2之间的强类型。