Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可以用常量值命名函数吗?_C#_Asp.net Mvc 4 - Fatal编程技术网

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之间的强类型。