将结构体作为参数传递给String.Format函数

3
可以像这样使用结构体作为string.Format的参数吗?
struct kid
{
    public string name;
    public int age;
};

kid.name = alice;
kid.age = 2;

Console.WriteLine(String.Format("Her name is {0} and she's {1} years old", kid));

改为这样:

Console.WriteLine(String.Format("Her name is {0} and she's {1} years old", kid.name ,kid.age));

编辑:

这个字符串将在运行时从配置文件中读取


不行。{0}和{1}是两个不同的属性,你不能从一个名为'kid'的对象中获取它们。 - jdweng
2
顺便提一下,对于Console.WriteLine,您不需要使用string.Format,因为WriteLine方法执行相同的操作并以相同的方式接受参数。 - mbrdev
理论上,一个结构体和一个类都可以创建一个索引器(如果我没记错的话),然后它可能等同于一个字符串数组...现在我没有编译器来验证这个答案。 - user6996876
你能在结构体中重写 ToString() 吗? - John Alexiou
4个回答

7

不行,它怎么知道要把属性放在哪里?

你可以使用c# 6.0的字符串插值,而不是以这种方式输入string.Format,像这样编写:

Console.WriteLine($"Her name is {kid.name} and she's {kid.age} years old");

也许可以重写ToString()方法来返回它:

struct kid
{
    public override string ToString()
    {
       return $"Her name is {name} and she's {age} years old";
    }
}

接着调用Console.WriteLine(kid.ToString());


1
嘿,去回答 Linq 的问题吧。字符串插值的部分就交给我了 :) - uTeisT
1
@uteist - 哈哈 :) 好吧..正在洗碗,突然看到那个问题。忍不住了。 - Gilad Green
我认为为了代码的清晰度,我会采用这个想法,谢谢。 - Arnon Hadas
@ArnonHadas - 很高兴听到这个好消息 :) - Gilad Green
这只能在编译时工作,我需要字符串能够在运行时更改。 - Arnon Hadas

1
由于.Format的签名是String.Format(string format, params object[] args),因此您可以将结构体转换为对象数组。
struct Kid
{
    public string name;
    public int age;

    public object[] ToObjectArray()
    {
        return new object[] {
            name, age };
    }
    public static implicit operator object[](Kid kid)
    {
        return kid.ToObjectArray();
    }
};

class Program
{
    static void Main(string[] args)
    {
        Kid kid=new Kid() { name="alice", age=2 };

        Console.WriteLine("Her name is {0} and she's {1} years old", kid);
        // Same as
        // Console.WriteLine(string.Format("Her name is {0} and she's {1} years old", kid));
    }
}

您还可以利用协变性,并使用以下方法将 string[] 隐式转换为 object[]
    public string[] ToStringArray()
    {
        return new string[] {
            name, age.ToString() };
    }
    public static implicit operator object[](Kid kid)
    {
        return kid.ToStringArray();
    }

而不是使用 ToObjectArray()


1
太好了,我一直在尝试着达到那个目标,但是使用在线编译器在手机上实在太困难了。 - user6996876

1
你可以通过实现IFormattable接口并使用格式化字符串来访问不同的属性:
struct kid : IFormattable {
    public string name;
    public int age;
    public override string ToString() => ToString(null, null);
    public string ToString(string format, IFormatProvider provider) {
        switch(format) {
            case null:
            case "":
                return string.Format(provider, "({0:name}, {0:age})", this);
            case "name":
                return name.ToString(provider);
            case "age":
                return age.ToString(provider);
            default:
                throw new ArgumentOutOfRangeException(nameof(format));
        }
    }
}

然后您可以按以下方式编写它:
Console.WriteLine("Her name is {0:name} and she's {0:age} years old", kid);

0

可以将结构体作为数组进行访问,例如:

如果kid是一个结构体kidStr,那么kid[0]和kid[1]可以分别定义为name和age.ToString(),并在WriteLine中作为一对参数使用... 如果这对你有意义的话...

public string this[int i] { 
    get { return i == 0 ? name :  age. ToString(); }
}

或者更简单地说

public string[] ToArray() {
    return new string[2]{ name, age.ToString()};
}

在结构体kidStr中具有上述索引器和一个实例kid。
Console.WriteLine("name is {0}, age is {1}", kid[0], kid[1]); // or kid.ToArray()

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