Dynami c Шаблоны строк в C# - PullRequest
       45

Dynami c Шаблоны строк в C#

0 голосов
/ 25 января 2020

Я ищу способ выполнить интерполяцию строки, но где строка шаблона находится в переменной раньше времени, а не использовать true интерпретацию строки, где $ "{a} {b} "немедленно параметризуется и возвращается.

Есть множество мест, которые были бы полезны, но в качестве наиболее яркого примера я пишу конвейер ETL (Extract Transform Load), в котором есть десятки различных REST API, которые мне нужны ударить. Одни и те же два аргумента встречаются в разных URI неоднократно, и я хотел бы динамически заменить их значениями, предоставленными пользователем. Два таких примера перечислены ниже.

Это может быть легко выполнено с помощью интерполяции строк, если у меня есть значения, доступные во время выполнения, например, "

int projectId = 1;
int uploadId = 3;
string uri = $"http://www.example.com/project/{projectId}/data?uploadId={uploadId}";
/* evaluates to "http://www.example.com/project/1/data?uploadId=1" */

Однако я хочу построить поднимите эти параметризованные строки на раньше времени и сможете заменить их теми переменными, которые у меня есть в этом контексте. Другими словами, в псевдокоде:

int projectId = 1;
int uploadId = 3;
string uriTemplate = "http://www.example.com/project/{projectId}/data?uploadId={uploadId}";
string uri = ReplaceNameTags(uriTemplate, projectId, uploadId)
// example method signature
string ReplaceNametags(uriTemplate, params object[] args)
{
    /* insert magic here */
}

Отражение пришло на ум, может быть, я мог бы как-то собрать названия входов, но я не так хорош с рефлексией, и все мои попытки оказываются гораздо более сложными, чем если бы я вообще отказался от идеи.

String.Format() пришло на ум, но в идеале я не был бы ограничен порядковым положением предоставленных аргументов.

Я видел это поведение повсеместно (например, RestSharp, Swagger, ASP. NET Маршрутизация), но я не уверен, как подражать.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 января 2020

Вы можете передать аргументы как динамический c объект, выполнить итерацию по его ключам и использовать Regex для выполнения замены:

private string ReplaceNameTags(string uri, dynamic arguments)
    {
        string result = uri;
        var properties = arguments.GetType().GetProperties();
        foreach (var prop in properties)
        {
            object propValue = prop.GetValue(arguments, null);
            result = Regex.Replace(uri, $"{{{prop.Name}}}", propValue.ToString());
        }
        return result;
    }

Пример использования будет:

ReplaceNameTags(uri, new { projectId, uploadId });
0 голосов
/ 26 января 2020

Вы можете использовать позиционные заполнители вместо имен переменных и задокументировать, какая переменная идет в какую позицию.

int projectId = 1; //documented as the first value (position 0)
int uploadId = 3; //documented as the second value (position 1)

//supplied by end users... say, loaded from config file
string uriTemplate = "http://www.example.com/project/{0}/data?uploadId={1}";

string uri = string.Format(uriTemplate, projectId, uploadId);

Я также видел, что это было сделано с пустой строкой, идущей в позиции 0, так что для конечных пользователей имеет больше смысла, когда нумерация начинается с 1.

string uriTemplate = "http://www.example.com/project/{1}/data?uploadId={2}";
string uri = string.Format(uriTemplate, "", projectId, uploadId);
...