Динамическая интерполяция строк
Может ли кто-нибудь помочь мне с этим?
Требуемый вывод: "Задача 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);
}
Ответ 3
Вам нужна именованная строка. См. Сообщение Фила Хаака от лет назад: http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx/
Ответ 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));
Или что-то в этом роде.