C# 使用对象中的参数格式化字符串

C# 使用对象中的参数格式化字符串,c#,.net,C#,.net,我的数据库中有一个varchar列,上面有如下数据: "Hello my name is {person.firstname} and my house is in {city.name}" 我想将我的对象注入这个字符串中,以获得一个完整的数据字符串,其中包含来自数据库的数据 我使用的是.NET4.7,它在API上 这容易做到吗?我需要使用Roselyn代码分析吗 谢谢 这种方法需要大量代码 using System.Collections.Generic; using System.Linq

我的数据库中有一个varchar列,上面有如下数据:

"Hello my name is {person.firstname} and my house is in {city.name}"
我想将我的对象注入这个字符串中,以获得一个完整的数据字符串,其中包含来自数据库的数据

我使用的是
.NET4.7
,它在API上

这容易做到吗?我需要使用Roselyn代码分析吗


谢谢

这种方法需要大量代码

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

public class Program
{   
    public static void Main()
    {       
        var person = new{
            firstname = "Jim"
        };
        var city = new {
            name = "Mexico City"
        };
        var text = "Hello my name is {person.firstname} and my house is in {city.name}";

        foreach(var item in Program.ToDictionary(person, "person"))
            text = text.Replace(item.Key, item.Value);

        foreach(var item in Program.ToDictionary(city, "city"))
            text = text.Replace(item.Key, item.Value);

        Console.WriteLine(text);
    }

    private static Dictionary<string, string> ToDictionary(dynamic subj, string prefix){
        var json = JsonConvert.SerializeObject(subj);
        Dictionary<string, string>  deserialized = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
        var result = deserialized.ToDictionary(p => string.Format("{{{0}.{1}}}", prefix, p.Key), p=> p.Value);

        return result;
    }
}
使用System.Collections.Generic;
使用System.Linq;
使用Newtonsoft.Json;
公共课程
{   
公共静态void Main()
{       
var person=新{
firstname=“吉姆”
};
var城市=新{
name=“墨西哥城”
};
var text=“你好,我的名字是{person.firstname},我家在{city.name}”;
foreach(Program.ToDictionary(person,“person”)中的var项)
text=text.Replace(item.Key,item.Value);
foreach(Program.ToDictionary(city,“city”)中的var项)
text=text.Replace(item.Key,item.Value);
控制台写入线(文本);
}
专用静态字典ToDictionary(动态主题、字符串前缀){
var json=JsonConvert.SerializeObject(subc);
Dictionary deserialized=JsonConvert.DeserializeObject(json);
var result=反序列化的.ToDictionary(p=>string.Format(“{{{0}.{1}}}”,前缀,p.Key),p=>p.Value);
返回结果;
}
}
结果将是:

你好,我叫吉姆,我家在墨西哥城


您可以使用string.format:

或者你也可以自己把绳子连在一起:

var name = "Rick"; // Fill this with the data from the database
var location = "Zwolle, The Netherlands"    
var dataBaseItem = "Hello my name is " + name +  " and my house is in " + location
或者你可以使用字符串插值,我的最爱


我认为有多种解决方案对您有利也有弊。因此,我只想向您展示三种方法,如何将数据转换为特定的预定义字符串

1。使用“$”符号

这句话将是:“绝地武士的名字是卢克·天行者”

这个符号与数据库中的符号非常接近,但有一个非常重要的区别:上面的示例是在代码中完成的,句子WithFullName的定义也是如此。在您的例子中,您从数据库中获取“句子”,而上面的符号将不会以它的方式工作

2。使用String.Format

这句话将是:“绝地武士的名字是卢克·天行者”

它是如何工作的?Format()用给定的参数替换{x}。第一个参数是要格式化的字符串,其余参数是要成为格式化字符串一部分的值。但要小心:如果要替换例如五个值,则需要来自{0}、{1}、{2}、{3}、{4}的占位符,并为string.Format函数提供五个附加参数。就这样,

var sentenceWithFullname = string.Format("The Jedi's name is {0} {1} and his favorites numbers are: {2}, {3}, {4}", firstName, lastName, "0815", "1337", "4711");
private static string MakeResponse(IEnumerable<object> context, string name) {
  if (string.IsNullOrEmpty(name))
    return "???";
  else if (context == null)
    return "???";

  string[] items = name.Split('.');

  string className = items[0];
  string propertyName = items.Length > 1 ? items[1] : null;

  object data = context
    .Where(item => item != null)
    .FirstOrDefault(item => 
       string.Equals(item.GetType().Name, className, StringComparison.OrdinalIgnoreCase));

  if (null == data)
    return "???";

  if (null == propertyName)
    return data.ToString();

  var property = data
    .GetType()
    .GetProperties(BindingFlags.Public | 
                   BindingFlags.Instance | 
                   BindingFlags.Static)
    .Where(prop => string.Equals(prop.Name, propertyName, StringComparison.OrdinalIgnoreCase))
    .Where(prop => prop.CanRead)
    .Where(prop => !prop.GetIndexParameters().Any())
    .FirstOrDefault();

  if (null == property)
    return "???";

  return property.GetValue(property.GetGetMethod().IsStatic ? null : data)?.ToString() ?? "";
}
如果占位符的数量和参数的数量不匹配,则可能导致异常

3。使用string.Replace()

这句话将是:“绝地武士的名字是卢克·天行者”

这种方法很简单。从数据库中获取字符串,并用来自属性或变量的相应值替换占位符

我的建议

所以,如果我们现在尝试使这些解决方案适合您的问题,我不会选择解决方案一,因为您预定义的字符串来自数据库,并且没有在代码中定义。因此,上面的示例对您不起作用

如果您有机会更改数据库中的值,我建议您选择第二种解决方案。因此,使用{0}到{n}占位符定义字符串值,并对其使用string.Format()函数。如果数据库字符串格式为fix,则这也不适用于您


在我看来,我并不真正喜欢string.Replace()函数,但对于您的情况,它可以解决您的问题。当然,它包含很多神奇的字符串,很容易受到数据库站点上任何更改的影响。

对于给定字符串
源代码

  string source = 
    "Hello my name is {person.firstname} and my house is in {city.name}";
我们必须实施
2
步骤:首先,我们应该能够为一个给定的名字(比如
person.firstname
city.name
)提供正确的回答 (比如说,
“约翰”
“纽约”
)。如果您有某种上下文,则需要查询的实例集合,例如

  IEnumerable<object> = new List<object>() {
    new Person() {
      FirstName = "John",
      LastName  = "Smith",
      Sex       = "M",
      Age       = 44  
    },

    new City() {
      Name    = "New York",
      Country = "USA"
    },

    ...  
  };
演示:

public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

public class City {
  public string Name { get; set; }
}

...

var person = new Person() {
  FirstName = "John",
  LastName = "Smith",
},

var city = new City() {
  Name = "New York"
};

...

string stringToModify = 
  "Hello my name is {person.firstname} and my house is in {city.name}"; 

string result = ReplaceMyMask(stringToModify, person, city);

Console.Write(result);
Hello my name is John and my house is in New York
结果:

public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

public class City {
  public string Name { get; set; }
}

...

var person = new Person() {
  FirstName = "John",
  LastName = "Smith",
},

var city = new City() {
  Name = "New York"
};

...

string stringToModify = 
  "Hello my name is {person.firstname} and my house is in {city.name}"; 

string result = ReplaceMyMask(stringToModify, person, city);

Console.Write(result);
Hello my name is John and my house is in New York

这个QA会有一些很好的建议,这看起来就像你需要的。此外,您可能需要重新思考您的方法。从字符串解析代码通常不是一个好主意。考虑一下如果替换变量<代码>城市。名称<代码> > <代码>城市>值< /代码>。您必须编写一个sql查询来替换所有出现的
City.Name
,因为您更改了代码中某个变量的名称是,但不是:),因为我将有很多子属性,所以我希望它与给定的objectI一起使用,我想我有个主意。@AudricCh它仍然是基于
string.Replace
的解决方案,但如果您有多个对象,它可能会有所帮助。此外,还可以对其进行推广。字符串格式并不是我所期望的。我从“你好,我的名字是{person.firstname},我的房子在{city.name}”开始,我想要“你好,我的名字是toto,我的房子在纽约”,方法类似于replaceMysmask(stringToModify,person,house)@AudricCh-ah-在这种情况下,你能把这个信息添加到问题中让它更清楚吗?关于:string.replace({city.name}那么-这就是你的意思吗?嗨,谢谢分享!但在我的数据库中,我不知道参数的顺序。因此,我不能使用有序参数…因此,如果您不知道参数的顺序,我认为String.Replace()函数是唯一可以解决您的问题的函数。当然,您需要某种逻辑来负责将数据推送到正确的占位符中。但是,如果placeholde
private static string ReplaceMyMask(string source, params object[] context) {
  if (null == context)
    return source;

  return Regex.Replace(
    source,
  @"\{\s*[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*\s*}",
    match => MakeResponse(context, match.Value.Trim(' ', '{', '}'))
  );
}
public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

public class City {
  public string Name { get; set; }
}

...

var person = new Person() {
  FirstName = "John",
  LastName = "Smith",
},

var city = new City() {
  Name = "New York"
};

...

string stringToModify = 
  "Hello my name is {person.firstname} and my house is in {city.name}"; 

string result = ReplaceMyMask(stringToModify, person, city);

Console.Write(result);
Hello my name is John and my house is in New York