Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET:是否有用于将对象属性值插入字符串的String.Format表单?_.net_String_String.format - Fatal编程技术网

.NET:是否有用于将对象属性值插入字符串的String.Format表单?

.NET:是否有用于将对象属性值插入字符串的String.Format表单?,.net,string,string.format,.net,String,String.format,我认为这个问题的直接答案是‘不’,但我希望有人编写了一个真正简单的库来实现这一点(或者我可以做到……呃……) 让我用一个例子来说明我在寻找什么。 假设我有以下几点: class Person { string Name {get; set;} int NumberOfCats {get; set;} DateTime TimeTheyWillDie {get; set;} } 我希望能够做到以下几点: static void Main() { var p1 = new Pers

我认为这个问题的直接答案是‘不’,但我希望有人编写了一个真正简单的库来实现这一点(或者我可以做到……呃……)

让我用一个例子来说明我在寻找什么。 假设我有以下几点:

class Person {
  string Name {get; set;}
  int NumberOfCats {get; set;}
  DateTime TimeTheyWillDie {get; set;}
}
我希望能够做到以下几点:

static void Main() {
  var p1 = new Person() {Name="John", NumberOfCats=0, TimeTheyWillDie=DateTime.Today};
  var p2 = new Person() {Name="Mary", NumberOfCats=50, TimeTheyWIllDie=DateTime.Max};

  var str = String.Format(

"{0:Name} has {0:NumberOfCats} cats and {1:Name} has {1:NumberOfCats} cats.  They will die {0:TimeTheyWillDie} and {1:TimeTheyWillDie} respectively
", p1, p2);

  Console.WriteLine(str);
}
var person = new Person { Name = "joe", Email = new Email { Address = "joe@joe.com" } };

var message = string.Format("{0}'s e-mail is {1}",
    ExpressionEvaluator.GetValue(person, "Name"), 
    ExpressionEvaluator.GetValue(person, "Email.Address"));

有人知道这样做是否有一种格式,或者是否有人编写了一个库来实现它?我知道这应该不会太难,但我不想重新实现控制盘。

您可以为您的类重写ToString()

好文章

将“:”后面的内容作为参数传递给类的ToString方法。
只需声明一个接受字符串的ToString方法,“Name”、“NumberOfCats”等将传入该参数

编辑:必须实现System.IFormattable。这项工作:

class Person : IFormattable
{
    public override string ToString()
    {
        return "Person";
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {
        if (format == "Name")
        {
            return "John";
        }
        if (format == "NumberOfCats")
        {
            return "12";
        }
        return "Unknown format string";
    }

}

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        Console.WriteLine(string.Format("Name = {0:Name}",p));
        Console.WriteLine(string.Format("NumberOfCats = {0:NumberOfCats}", p));
    }
}

我真的不明白这是怎么回事:

"{0:Name} has {0:NumberOfCats} cats and {1:Name} has {1:NumberOfCats} cats.  They will die {0:TimeTheyWillDie} and {1:TimeTheyWillDie} respectively", p1, p2);
还有比这更好的吗

"{0} has {1} cats and {2} has {3} cats.  They will die {4} and {5} respectively
", p1.Name, p1.NumberOfCats, p2.Name, p2.NumberOfCats, p1.TimeTheyWillDie, p2.TimeTheyWillDie);
事实上,由于您在第一个版本中失去了intellisense帮助,它不仅更容易失败,而且可能需要更长的时间才能在IDE中编写


如果你想做这样的事情,你可以随时为它设计一个扩展方法。我打赌这看起来会像一场噩梦,tho.

这是Python世界中许多人使用“someString%locals()”所做的事情。不过,您的建议与string.format的工作方式有一些根本性的区别:

  • 通常,占位符符号在冒号后面有字符串格式信息,而您希望进行属性访问

  • 占位符索引({0,{1等)通常引用params args中的numbers参数,但您似乎希望函数为传入的每个参数呈现整个字符串。它们是否应该连接?作为字符串数组返回


因此,您可能会自己编写这个,在这种情况下,您可以完全跳过索引符号(因此{NumberOfCats}而不是{0:NumberOfCats}),或者甚至使用属性名后跟格式提供程序{NumberOfCats:c}。从输入对象中使用元数据应该不会太难。


<>你最好做的是提供你自己的IfMatalPosivor,并手动解析输入(蹩脚的部分…)。< / P> < P>如果你决定自己解析格式字符串,你应该考虑这个……/P> Spring.NET项目在Spring.Core中具有。它允许您通过使用字符串指向属性来查询对象图。使用您的示例,您可以想象如下情况:

static void Main() {
  var p1 = new Person() {Name="John", NumberOfCats=0, TimeTheyWillDie=DateTime.Today};
  var p2 = new Person() {Name="Mary", NumberOfCats=50, TimeTheyWIllDie=DateTime.Max};

  var str = String.Format(

"{0:Name} has {0:NumberOfCats} cats and {1:Name} has {1:NumberOfCats} cats.  They will die {0:TimeTheyWillDie} and {1:TimeTheyWillDie} respectively
", p1, p2);

  Console.WriteLine(str);
}
var person = new Person { Name = "joe", Email = new Email { Address = "joe@joe.com" } };

var message = string.Format("{0}'s e-mail is {1}",
    ExpressionEvaluator.GetValue(person, "Name"), 
    ExpressionEvaluator.GetValue(person, "Email.Address"));

(我可能不会存储这样的电子邮件,但我想不出更好的)

编辑:您不必为每个对象实现IFormattable…这将是一个PITA,严重限制和相当大的维护负担。只需将反射和IFormatProvider与ICustomFormatter一起使用,它就可以处理任何对象。String.Format有一个重载,可以将其作为参数

我以前从未想过这一点,但你让我很感兴趣,所以我不得不快速地尝试一下。请注意,我选择了允许将额外的格式字符串传递给属性值,并且它只适用于非索引和可访问的属性(尽管您可以轻松地添加)

还有你稍加修改的例子:

var p1 = new Person() {Name="John", NumberOfCats=0, TimeTheyWillDie=DateTime.Today};
var p2 = new Person() {Name="Mary", NumberOfCats=50, TimeTheyWillDie=DateTime.MaxValue};

var str = string.Format(
    new ReflectionFormatProvider(),
    @"{0:Name} has {0:NumberOfCats} cats and {1:Name} has {1:NumberOfCats} cats. 
    They will die {0:TimeTheyWillDie:MM/dd/yyyy} and {1:TimeTheyWillDie} respectively.
    This is a currency: {2:c2}.", 
    p1, 
    p2,
    8.50M
);

Console.WriteLine(str);
产出:

John has 0 cats and Mary has 50 cats. 
They will die 12/10/2008 and 12/31/9999 11:59:59 PM respectively.
This is a currency: $8.50.
查看我的图书馆“扩展版”

在Nuget上:


在GitHub上:

我只是想知道你为什么这么恨John?你知道,他没有猫。宠物可以延长寿命。这是科学!嗯,好主意,如果你写一个共享,它不会有帮助,因为他在同一个字符串中组合了多个实例。还有:你真的想这么做,还是会有另一个。ToString()你可能想要的解释?啊,我明白你的意思了。不过这太混乱了。而且这是一种非常有限的方法。编写自己的字符串会更容易。如果你想在字符串中公开多个属性,格式是更有用的。尤其是使用IFormattable接口。我认为这不是真的,ToString()不接受任何参数这是一个好主意!在许多以字符串或IFormatProvider作为参数的.NET对象上都存在ToString重载,但不幸的是,正如George Mauer指出的,这些在对象上不存在。这是一个很好的编辑。但是的,如果这是你的意思,那实际上是一个非常好的主意……不,不是我的意思是,我只是一开始就弄错了:)很多时候我都没有用C#编程。在我的pov字符串中。Format是一种简单的视图引擎,为什么它会有更多的限制?如果你有一个稳定的域模型,在配置中定义输出字符串的精确格式应该没有问题。这会很方便。第二点不是这样。{0:NumberOfCats}表示p1.NumberOfCats,其中p1是第一个位置参数。虽然第一点很好,但它确实需要一些额外的语法标记。非常流畅…非常流畅