【问题标题】:C# automatic casting when calling overloaded function调用重载函数时的C#自动转换
【发布时间】:2017-09-12 12:49:16
【问题描述】:

假设我有以下重载函数:

void DoSomething(int x) { ... }
void DoSomething(float x) { ... }
void DoSomething(decimal x) { ... }

在下面的方法中,我需要调用正确的重载。这是一个简单实现的样子:

void HaveToDoSomething(object data)
{
    if (data is int) DoSomething((int)data);
    else if (data is float) DoSomething((float)data);
    else if (data is decimal) DoSomething((decimal)data);
}

当要检查大约 20 种类型时,这很乏味。有没有更好的方法来自动进行所有这些转换?

我忘了提一点:DoSomething 不适用于泛型,因为每种类型都需要以不同方式处理,而我只知道运行时的类型。

【问题讨论】:

  • 使DoSomething 通用
  • 你能改变DoSomething的实现吗?
  • 你从哪里得到data?它的来源没有提供任何关于它的类型的信息?
  • @TimSchmelter 我认为泛型不适用于我的情况,每种类型都需要以不同方式处理。例如,如果您需要将数据序列化为特定格式,则需要对每种类型进行不同的处理。
  • @mjwills 是的,动态是我认为我曾经见过的方法,但忘记了。 “反射”方法更有用,因为它也可以在 Java 中应用。我不知道该选择哪个答案,因为只有一个,而且两个都有帮助。

标签: c# casting operator-overloading


【解决方案1】:

一种可能的方法是使用dynamic

void HaveToDoSomething(dynamic data)
{
    DoSomething(data);
}

【讨论】:

  • 请注意,虽然这种方法看起来很简洁,但在使用时可能会导致性能损失,例如在一个紧密的循环中。
  • 这是正确的@dymanoid - dynamic 可能会对性能产生影响。在这种情况下是否是一个问题很难说。
  • 由于除泛型之外的任何解决方案都将涉及反射,这似乎是一个好方法。
  • @MatthewWatson OP 的(工作)代码不涉及反射。
  • @Servy 不是在 OP 问题的上下文中:“有没有更好的方法来自动进行所有这些转换?” - 据我所知,任何涉及“自动转换”的解决方案都将涉及反射(除了涉及使用特殊工具在编译时生成代码的解决方案......)
【解决方案2】:

您可以使用Reflection,但它会影响性能:

public class Example
{
    void DoSomething(int i)
    {

    }

    void DoSomething(float i)
    {

    }
}

public static class ExampleExtensions
{
    public static void DoSomethingGeneric(this Example example, object objectParam)
    {
        var t = objectParam.GetType();
        var methods = typeof(example).GetMethods().Where(_ => _.Name == "DoSomething");
        var methodInfo = methods.Single(_ => _.GetParameters().First().ParameterType == t);
        methodInfo.Invoke(example, new[] { objectParam });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多