Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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#_Refactoring - Fatal编程技术网

C# 将许多方法中使用的一个硬编码字符串重构为两个

C# 将许多方法中使用的一个硬编码字符串重构为两个,c#,refactoring,C#,Refactoring,我有一个类似于下面的情况。它是一个RESTAPI助手类,具有用于不同API端点的方法,并向其提供头。一个标题ChannelId已硬编码为“Channel 1” 从现在起,应该有可能改用“通道2”。什么是重构这个的好策略?我已经提出了我的建议,但不知何故,这似乎是一种廉价的方式。因为我需要改变很多方法中的签名 public class RestApiRequestHelper { public void MethodA() { var request = new R

我有一个类似于下面的情况。它是一个RESTAPI助手类,具有用于不同API端点的方法,并向其提供头。一个标题ChannelId已硬编码为“Channel 1”

从现在起,应该有可能改用“通道2”。什么是重构这个的好策略?我已经提出了我的建议,但不知何故,这似乎是一种廉价的方式。因为我需要改变很多方法中的签名

public class RestApiRequestHelper
{
    public void MethodA()
    {
        var request = new RestRequest(RestRequest.GET);
        AddHeaders(request);
        //...

    }

    //... more similar methods using AddHeaders(request)

    public void MethodZ()
    {
        
        var request = new RestRequest(RestRequest.GET);
        AddHeaders(request);
        //...
    }

    private void AddHeaders(RestRequest request)
    {
        request.AddHeader("ChannelId", "Channel 1");
        //...
    }
}
我的建议是:

public class RestApiRequestHelper
{
    public void MethodA(string channelId)
    {
        var request = new RestRequest(RestRequest.GET);
        AddHeaders(request, channelId);
        //...
    }

    //... more similar methods using AddHeaders(request)

    public void MethodZ(string channelId)
    {
        var request = new RestRequest(RestRequest.GET);
        AddHeaders(request, channelId);
        //...
    }

    private void AddHeaders(RestRequest request, string channelId)
    {
        request.AddHeader("ChannelId", channelId);
        //...
    }
}

从API消费者的角度来看,新版本是一个突破性的变化,而且很容易出错

  • 突破性变化:消费者必须适应新的API,因为它不向后兼容
  • 容易出错:消费者现在几乎可以用任何东西调用此API,例如:
    null
    “ThisIsNotExistingChannelId”
    “ThisisMisspelledChannelId”
    等待长时间运行操作ToobtainChannelId()
    ,等等
向后兼容性 如果您不想引入突破性的更改(这样您的客户机就可以在不更改任何代码的情况下使用API),那么您可以使用可选参数

具有默认值的参数
公共无效方法A(字符串channelId=“通道1”)
{
var请求=新的RestRequest(RestRequest.GET);
addHeader(请求,channelId);
//...
}
具有回退值的参数
public void MethodA(字符串channelId=default)
{
var请求=新的RestRequest(RestRequest.GET);
AddHeader(请求,通道ID??“通道1”);
//...
}
参数限制 如果您不想允许任何类型的通道标识符,那么您也可以限制它

运行时检查
私有静态只读不可变数组
ValidChannelIds=ImmutableArray.Create(“通道1”、“通道2”);
public void MethodA(字符串channelId=default)
{
如果(!ValidChannelIds.Contains(channelId))
抛出新ArgumentOutOfRangeException(nameof(channelId)),
$“提供的通道无效。有效ID为:{string.Join(',',ValidChannelIds)}'”;
...
}
编译时和运行时检查
公共枚举通道
{
[说明(“频道1”)]
Ch1=0,
[说明(“频道2”)]
Ch2=2,
}
公共无效方法A(通道channelId=Channels.Ch1)
{
如果(!Enum.IsDefined(typeof(Channels),channelId))
抛出新ArgumentOutOfRangeException(nameof(channelId)),
$“提供的通道无效。有效ID:“{string.Join(',',Enum.GetNames(typeof(通道)))}”;
var fieldInfo=typeof(Channels.GetField(channelId.ToString(“G”));
var chId=fieldInfo.GetCustomAttribute().Description;
...
}

需要
Enum.IsDefined
,因为您也可以这样调用方法:
MethodA((Channels)3)和3没有
说明

为什么没有?这是正常的,您也可以将其提取到扩展方法
AddChannelIdHeader(此重新请求请求,字符串channelId){request.AddHeader(“channelId”,channelId);}
。如果您的“channel2”方法与channel1不相关,您可以添加另一个方法,将头添加到请求中。在您回答之前,我选择了“带默认值的参数”选项,但非常感谢您的回答。