gpt4 book ai didi

c# - C# 方法可以定义可变数量的对象参数和可变数量的整数参数吗?

转载 作者:行者123 更新时间:2023-11-30 20:28:03 25 4
gpt4 key购买 nike

C# 方法能否以这种简单方式或其他一些为调用方提供的简单方式定义可变数量的对象参数和可变数量的整数参数?

简单是什么意思?
从调用者的角度来看很简单。优先考虑所需的最少输入/字符,并且易于理解和使用。

为了什么目的?
动机是 Console.WriteLine 的基本包装器,它可以更轻松地输出分栏文本。现有的表示法不直观(例如,它需要负数)。对于一些基本场景,它也比需要的更冗长。

一个看起来很理想的答案(如果可能的话)将展示如何使用两个元组定义这样的方法,每个元组有 n 个值(或者嘿,最多说 10 个值)。我们的想法是它可以将调用者代码减少为:

// Output items given column widths
Console.WriteCols(("Name", "Address", "Age"), (20, 10, 30))
Console.WriteCols(("John", "123 Street", 28), (20, 10, 30))
Console.WriteCols(("Mary", "456 Street"), (20, 10))


我知道这只是一个值列表,但这适合我们的大多数列用例,而且,如果第一个示例是可能的,则似乎可以在需要时稍后添加字符串变量,例如:

Console.WriteCols(("{0} John", "123 Street", 28), (20, 10, 30), ("Dr."))

好吧,有什么问题吗?
对于第一个基本示例,我尝试了几种方法。一个关键点是我没有找到一种方法来计算元组的值。也许它在盯着我看,或者我把它复杂化了。第一个想法是只使用 2 个元组创建方法重载,每个元组最多允许 10 个值。然后所有重载都会调用一个主要方法来完成工作。但是,如果主要方法正在接收具有不同数量项目的松散类型元组,那么如果无法知道元组值的计数,则不清楚如何以通用方式处理所有重载情况。

最佳答案

public static class MyConsole
{
public static void Test()
{
Console.Out
.Columns(10, 40, 60)
.WriteLine("foo", "bar", "baz")
.WriteLine("LOL", "WUT", "BBQ")
.WriteLine("HA", "ha", "ha");

var cols = Console.Error.Columns(10, 40, 30);

cols.WriteLine("Mary", "Had", "a");
cols.WriteLine("Little", "lamb", "it's");
}

public static ColumnWriter Columns(params int[] widths) => new ColumnWriter(Console.Out, widths);
public static ColumnWriter Columns(this TextWriter writer, params int[] widths) => new ColumnWriter(writer, widths);

public class ColumnWriter
{
public ColumnWriter(TextWriter writer, int[] widths)
{
Debug.Assert(writer != null);
Debug.Assert(widths != null);

_writer = writer;
_widths = widths;
}
private TextWriter _writer;
private int[] _widths;

public ColumnWriter Line()
{
_writer.WriteLine();
return this;
}

public ColumnWriter Write(params object[] args)
{
Debug.Assert(args.Length == _widths.Length);

var count = Math.Min(_widths.Length, args.Length);
for (int idx = 0; idx < count; ++idx)
{
var fmt = "{0," + _widths[idx] + "}";
_writer.Write(fmt, args[idx]);
}

return this;
}
public ColumnWriter WriteLine(params object[] args)
{
return Write(args).Line();
}
}
}

这可以通过为 Columns(string formatString)Columns(this TextWriter writer, string formatString) 添加重载来改进。


坏主意

Columns() 可以返回一个委托(delegate),用于一些看起来很奇怪的语法(感谢 Evk 向我展示了方法——并且比我更喜欢这种语法)。更糟糕的是,我们可以给它多个索引器重载。

我不喜欢这两种情况下的新语法。这行得通,但任何在生产代码中使用其中任何一个的人都会偷羊:

public static class MyConsole
{
public static void Test()
{
// Not a great idea.
MyConsole.WriteLines(10, 10)("foo", "bar")("baz", "planxty");

// Truly awful idea.
MyConsole.Columns(10, 10)["foo", "bar"]["baz", "planxty"].End();
}

public static ColumnWriter Columns(params int[] widths) => new ColumnWriter(widths);

#region Not a great idea
// Evk showed me how to make this work.
public delegate Params Params(params object[] values);
public static Params WriteLines(params int[] widths)
{
var writer = new ColumnWriter(widths);

return new Params(writer.WriteLineParams);
}
#endregion Not a great idea

public class ColumnWriter
{
public ColumnWriter(int[] widths)
{
_widths = widths;
}
private int[] _widths;

#region Truly awful idea.
public ColumnWriter this[object o] => WriteLine(o);
public ColumnWriter this[object o1, object o2] => WriteLine(o1, o2);
public ColumnWriter this[object o1, object o2, object o3] => WriteLine(o1, o2, o3);

// ...moar overloards...

// In C# x[0]; is an expression, not a statement.
// x[0].End(); is a statement. Horrible, most horrible.
// Maybe I should name it FireMe() instead of End()
public void End() { }
#endregion Truly awful idea.

public ColumnWriter Line()
{
Console.WriteLine();
return this;
}

public ColumnWriter Write(params object[] args)
{
var count = Math.Min(_widths.Length, args.Length);
for (int idx = 0; idx < count; ++idx)
{
var fmt = "{0," + _widths[idx] + "}";
Console.Write(fmt, args[idx]);
}

return this;
}
public ColumnWriter WriteLine(params object[] args)
=> Write(args).Line();

#region Not a great idea
public Params WriteLineParams(params object[] args)
{
WriteLine(args);

return WriteLineParams;
}
#endregion Not a great idea
}
}

关于c# - C# 方法可以定义可变数量的对象参数和可变数量的整数参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47891394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com