gpt4 book ai didi

c#-4.0 - 重载接受 `object` 作为默认参数类型的方法

转载 作者:行者123 更新时间:2023-12-02 08:00:25 25 4
gpt4 key购买 nike

我需要能够调用方法并传入未知类型的对象但随后调用正确的重载。我还需要一个接受的默认实现object 作为其参数类型。我看到的是默认重载是唯一被使用过的重载。

这是我想做的事情的要点:

class Formatter
{
private object Value;

public Formatter(object val){
Value = val;
}

public override string ToString()
{
return Format(Value);
}

private string Format(object value)
{
return value.ToString();
}

private string Format(DateTime value)
{
return value.ToString("yyyyMMdd");
}
}

好的,到目前为止一切顺利。现在我希望能够做到这一点:

public static class FancyStringBuilder()
{
public static string BuildTheString()
{
var stringFormatter = new Formatter("hello world");
var dateFormatter = new Formatter(DateTime.Now);
return String.Format("{0} {1}", stringFormatter, dateFormatter);
}
}

FancyStringBuilder.BuildTheString() 的结果是 "hello world 2012-12-21 00:00:00.000",而我预期的是 "hello world 20121221"

问题是接受 DateTime 的重载没有被调用,而是默认为接受 object 的重载。 如何在不使用困惑的 switch 语句的情况下调用正确的方法?

最佳答案

Formatter.ToString() 中,始终调用重写 Formatter.Format(object)。这是因为重载决策发生在编译时,而不是运行时。在编译时,关于 Value 唯一已知的是它是一个对象。

如果您确实想区分传入类型,则需要在 Formatter 的构造函数中执行此操作。在这种情况下,您可以立即调用 ToString() 并仅存储格式化结果,而不是卡在该对象上:

class Formatter
{
string formattedValue;

public Formatter(object value)
{
formattedValue = value.ToString();
}

public Formatter(DateTime value)
{
formattedValue = value.ToString("yyyyMMdd");
}

public string ToString()
{
return formattedValue;
}
}

请注意,这确实假设您的对象在创建 Formatter 对象的时间和调用 Formatter.ToString() 的时间之间没有发生变化,或者在至少可以在创建 Formatter 时拍摄字符串表示形式的快照。

这还假设您在编译时知道传入的类型。如果您想要一个真正仅运行时的解决方案,则必须使用“is”运算符或 typeof() 比较。

如果您的目标只是根据传入类型提供自定义 ToString() 格式,我可能会使用从类型映射到格式字符串的列表来实现:

static class Formatter
{
private static List<Tuple<Type, string>> Formats;

static Formatter()
{
Formats = new List<Tuple<Type, string>>();

// Add formats from most-specific to least-specific type.
// The format string from the first type found that matches
// the incoming object (see Format()) will be used.
AddMapping(typeof(DateTime), "yyyyMMdd");
// AddMapping(typeof(...), "...");
}

private static void AddMapping(Type type, string format)
{
Formats.Add(new Tuple<Type, string>(type, format));
}

public static string Format(object value)
{
foreach (var t in Formats)
{
// If we find a type that 'value' can be assigned to
// (either the same type, a base type, or an interface),
// consider it a match, and use the format string.
if (t.Item1.IsAssignableFrom(value.GetType()))
{
return string.Format(t.Item2, value);
}
}

// If we didn't find anything, use the default ToString()...
return value.ToString();
}
}

这样,调用代码就如下所示:

Console.WriteLine(
"{0} {1}",
Formatter.Format(DateTime.Now),
Formatter.Format("banana"));

关于c#-4.0 - 重载接受 `object` 作为默认参数类型的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13962582/

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