Динамическая интерполяция строк

Может ли кто-нибудь помочь мне с этим?

Требуемый вывод: "Задача Todo для администратора"

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(ReplaceMacro("{job.Name} job for admin", new Job { Id = 1, Name = "Todo", Description="Nothing" }));
        Console.ReadLine();
    }

    static string ReplaceMacro(string value, Job job)
    {
        return value; //Output should be "Todo job for admin"
    }
}

class Job
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

Ответ 1

Два предложения:

DataBinder.Eval

string ReplaceMacro(string value, Job job)
{
    return Regex.Replace(value, @"{(?<exp>[^}]+)}", match => {
        return (System.Web.UI.DataBinder.Eval(new { Job = job }, match.Groups["exp"].Value) ?? "").ToString();
    });
}

Linq.Expression

Используйте класс Dynamic Query, указанный в MSDN LINQSamples:

string ReplaceMacro(string value, Job job)
{
    return Regex.Replace(value, @"{(?<exp>[^}]+)}", match => {
        var p = Expression.Parameter(typeof(Job), "job");
        var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups["exp"].Value);
        return (e.Compile().DynamicInvoke(job) ?? "").ToString();
    });
}

По-моему, выражение Linq.Expression более мощное, поэтому , если вы доверяете входной строке, вы можете делать более интересные вещи, то есть:

value = "{job.Name.ToUpper()} job for admin"
return = "TODO job for admin"

Ответ 2

Вы не можете использовать интерполяцию строк таким образом. Но вы все равно можете использовать метод pre-С# 6, используя string.Format:

static void Main(string[] args)
{
    Console.WriteLine(ReplaceMacro("{0} job for admin", new Job { Id = 1, Name = "Todo", Description = "Nothing" }));
    Console.ReadLine();
}

static string ReplaceMacro(string value, Job job)
{
    return string.Format(value, job.Name);
}

Ответ 4

Ответ от @ThePerplexedOne лучше, но если вам действительно нужно избегать строковой интерполяции, значит

static string ReplaceMacro(string value, Job job)
{
    return value?.Replace("{job.Name}", job.Name); //Output should be "Todo job for admin"
}

Ответ 5

Вы должны изменить свою функцию на:

static string ReplaceMacro(Job obj, Func<dynamic, string> function)
{
    return function(obj);
}

И назовите его:

Console.WriteLine(
    ReplaceMacro(
        new Job { Id = 1, Name = "Todo", Description = "Nothing" },
        x => $"{x.Name} job for admin"));

Ответ 6

Это общее решение Расширить ответ, предоставленный @Dan
Может использоваться для любого типизированного объекта.

установить System.Linq.Dynamic

     Install-Package System.Linq.Dynamic -Version 1.0.7 

    string ReplaceMacro(string value, object @object)
    {
        return Regex.Replace(value, @"{(.+?)}", 
        match => {
            var p = Expression.Parameter(@object.GetType(), @object.GetType().Name);                
            var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { p }, null, match.Groups[1].Value);
            return (e.Compile().DynamicInvoke(@object) ?? "").ToString();
        });
    }

Посмотреть рабочую демонстрацию для типа клиента

Ответ 7

Не совсем, но с битовой настройкой, я создал общую интерполяцию, которая поддерживает только поля/свойства.

public static string Interpolate(this string template, params Expression<Func<object, string>>[] values)
        {
            string result = template;
            values.ToList().ForEach(x =>
            {
                MemberExpression member = x.Body as MemberExpression;
                string oldValue = $"{{{member.Member.Name}}}";
                string newValue = x.Compile().Invoke(null).ToString();
                result = result.Replace(oldValue, newValue);
            }

                );
            return result;
        }

Прецедент

 string jobStr = "{Name} job for admin";
        var d = new { Id = 1, Name = "Todo", Description = "Nothing" };
        var result = jobStr.Interpolate(x => d.Name);

Другая

            string sourceString = "I wanted abc as {abc} and {dateTime} and {now}";
        var abc = "abcIsABC";
        var dateTime = DateTime.Now.Ticks.ToString();
        var now = DateTime.Now.ToString();
        string result = sourceString.Interpolate(x => abc, x => dateTime, x => now);

Ответ 8

Обернуть строку в функцию...

var f = x => $"Hi {x}";

f("Mum!");

//... Hi Mum!

Ответ 9

Я действительно не понимаю смысл вашего метода ReplaceMacro...

Но вот как это должно работать:

class Program
{
    static void Main(string[] args)
    {
        var job = new Job { Id = 1, Name = "Todo", Description = "Nothing" };
        Console.WriteLine($"{job.Name} job for admin");
        Console.ReadLine();
    }
}

Но если вам действительно хочется динамического ощущения, ваш метод ReplaceMacro должен просто взять один параметр, который является заданием:

static string ReplaceMacro(Job job)
{
    return $"{job.Name} job for admin.";
}

И используйте его как:

var job = new Job { Id = 1, Name = "Todo", Description = "Nothing" };
Console.WriteLine(ReplaceMacro(job));

Или что-то в этом роде.