在运行时设置 String.Format

4

我有一个XML文件,我希望允许最终用户设置字符串的格式。

例如:

<Viewdata>
<Format>{0} - {1}</Format>
<Parm>Name(property of obj being formatted)</Parm>
<Parm>Phone</Parm>
</Viewdata>

在运行时,我需要以某种方式将其转换为 String.Format("{0} - {1}", usr.Name, usr.Phone);

这种转换可行吗?


1
我想使用反射机制或许是可能的,但这听起来像是 XY 问题。 - Sayse
6个回答

3
当然。格式化字符串只是普通的字符串。
 string fmt = "{0} - {1}";    // get this from your XML somehow
 string name = "Chris";
 string phone = "1234567";

 string name_with_phone = String.Format(fmt, name, phone);

请注意,因为您的最终用户可能会干扰程序,请小心处理。不要忘记FormatException


1
姓名和电话似乎是对象的属性,所以我认为这样做行不通(这也是我的第一反应)。 - Sayse
@Sayse:仍然可以在“user”类中执行此操作。或者只需调用 String.Format(fmt, usr.Name, usr.Phone) - Bart Friederichs
1
是的,但我想需要更通用的东西(其中字段未知)。 - Sayse
正确。它将始终是(User)类型,但我希望最终用户设置格式以及在String.Format()期间将使用哪些obj属性。 - Chris
1
@Chris。我明白了。不过我不会这样实现,因为这样会将你的类暴露给最终用户。我会创建一些格式字符串,比如{name} - {phone}并记录哪些属性可以接受。然后使用字符串替换来创建格式字符串。这也可以保护你免受用户进行像{0:-10000000000000000000000000}这样的操作。 - Bart Friederichs
@BartFriederichs:是的,我一开始也是这么想的,希望有更好的方法。不过可能还是要采用这种方式。 - Chris

1
我同意其他帖子中说的,你可能不应该这样做,但这并不意味着我们不能玩一下这个有趣的问题。首先,这个解决方案是半成品/粗糙的,但如果有人想要建立它,这是一个很好的开始。 我在 LinqPad 中编写了它,我很喜欢它,所以 Dump() 可以用控制台输出代替。
void Main()
{
    XElement root = XElement.Parse(
@"<Viewdata>
    <Format>{0} | {1}</Format>
    <Parm>Name</Parm>
    <Parm>Phone</Parm>
</Viewdata>");

    var formatter = root.Descendants("Format").FirstOrDefault().Value;
    var parms = root.Descendants("Parm").Select(x => x.Value).ToArray();

    Person person = new Person { Name = "Jack", Phone = "(123)456-7890" };

    string formatted = MagicFormatter<Person>(person, formatter, parms);
    formatted.Dump();
/// OUTPUT ///
/// Jack | (123)456-7890
}

public string MagicFormatter<T>(T theobj, string formatter, params string[] propertyNames)
{
    for (var index = 0; index < propertyNames.Length; index++)
    {
        PropertyInfo property = typeof(T).GetProperty(propertyNames[index]);
        propertyNames[index] = (string)property.GetValue(theobj);
    }

    return string.Format(formatter, propertyNames);
}

public class Person
{
    public string Name { get; set; }
    public string Phone { get; set; }
}

0

您可以使用System.Linq.Dynamic,并使整个格式命令可编辑:

class Person
{
    public string Name;
    public string Phone;

    public Person(string n, string p)
    {
        Name = n;
        Phone = p;
    }
}

static void TestDynamicLinq()
{
    foreach (var x in new Person[] { new Person("Joe", "123") }.AsQueryable().Select("string.Format(\"{0} - {1}\", it.Name, it.Phone)"))
        Console.WriteLine(x);
}

0
XElement root = XElement.Parse (
@"<Viewdata>
<Format>{0} - {1}</Format>
<Parm>damith</Parm>
<Parm>071444444</Parm>
</Viewdata>");


var format =root.Descendants("Format").FirstOrDefault().Value;

var result = string.Format(format, root.Descendants("Parm")
                                     .Select(x=>x.Value).ToArray());

他希望将params数组作为用户对象调用。 - phillip

0

0

简短的回答是:是的,但这取决于您格式选项的种类,难度会有所不同。

如果您有一些格式化字符串可以接受5个参数,而另一些只能接受3个参数,那么您需要考虑这一点。

我建议使用解析XML获取参数,并将它们存储到对象数组中,以便传递给String.Format函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接