具有多种返回类型的方法

Posted

技术标签:

【中文标题】具有多种返回类型的方法【英文标题】:Method with Multiple Return Types 【发布时间】:2016-04-20 07:34:41 【问题描述】:

我已经查看了许多与此类似的问题,但没有一个真正涉及到我究竟想要做什么。我要做的是从外部源读取变量列表,这些变量也将它们的数据类型包含到字符串数组中:

例子:

ID/Key      Type    Value/Data; 
varName1    bool    true;
varName2    string  str;
varName3    int     5;

然后我将这些对象作为包含多个字符串的对象存储到字典中,ID 也用作键。

我现在要做的是创建一个使用 switch 语句的方法,该语句将字符串转换为正确的数据类型,并返回它而无需在方法调用中指定任何内容。该函数应如下所示:

public ??? Method(string key)

    if(dictionary.ContainsKey(ID))
    
        Var temp = dictionary[ID];

        switch (temp.Type)
        
            case "bool":
                return Convert.ToBoolean(temp.Value);

            case "int"
                return Convert.ToInt(temp.Value);

            case "string"
                return temp.Value;
        
    

    return "NULL"; 

方法调用应该如下所示:

int x = Method(string key);
string word = Method(string key);
bool isTrue = Method(string key);

也许我错过了一些东西,但我还没有找到真正能做到这样的东西。也欢迎任何和所有关于此的想法。

【问题讨论】:

对不起,C# 中没有这样的东西。方法具有固定的返回类型。您可以使用 object 作为您的返回类型,但您必须强制转换。 您必须使该方法具有通用性才能使其正常工作。当你使用它时,它最终看起来像string word = Method<string>(key)。此外,您还必须执行bool?int?,因为您想在找不到密钥时返回null 如果您的值存储为Object,您可以使用(T)value。是什么阻止了你 string word = (string)Method(string key);,给定,方法返回 object dynamic 怎么样? 你打算如何处理方法的返回值? 【参考方案1】:

在 C# 7 中,您可以选择从这样的方法返回多个值:

public (string SomeString, int SomeInt) DoSomething()  ... 

你可以得到这样的值:

var result = DoSomething();
Console.WriteLine(result.SomeString);
Console.WriteLine(result.SomeInt.ToString());

或者

(var someString, var someInt) = DoSomething();
Console.WriteLine(someString);
Console.WriteLine(someInt.ToString());

这适用于 Tuple 的表面之下,并且您不仅限于 2 个值。我不知道你可以返回多少,但我建议当你需要返回那么多值时,创建一个类。 更多信息:https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

【讨论】:

【参考方案2】:

编译器无法区分您提供的三个方法调用,因为它们看起来都像Method(key);

一种选择是返回object,然后期望消费代码将其转换为他们想要的:

public object Method(string key)

    if(dictionary.ContainsKey(key))
    
        var temp = dictionary[key];

        switch (temp.Type)
        
            case "bool":
                return Convert.ToBoolean(temp.Value);

            case "int"
                return Convert.ToInt(temp.Value);

            case "string"
                return temp.Value;
        
    

    return "NULL"; 


...

int x = (int) Method(key);
string word = (string) Method(key);
bool isTrue = (bool) Method(key);

您还可以使用 dynamic 关键字来隐式转换:

public dynamic Method(string key)

    if(dictionary.ContainsKey(key))
    
        var temp = dictionary[key];

        switch (temp.Type)
        
            case "bool":
                return Convert.ToBoolean(temp.Value);

            case "int"
                return Convert.ToInt(temp.Value);

            case "string"
                return temp.Value;
        
    

    return "NULL"; 


...

int x = Method(key);
string word = Method(key);
bool isTrue = Method(key);

但是,dynamic 是一个非常强大的概念,它很容易失控,所以你必须非常小心。

在我看来,您希望调用代码知道它希望为每个键获取哪种类型的对象。似乎最好的方法是让用户提供这些信息:

public T Method<T>(string key)

    if(dictionary.ContainsKey(key))
        return (T) Convert.ChangeType(dictionary[key].Value, typeof(T));
    return default(T);


...

int x = Method<int>(key);
string word = Method<string>(key);
bool isTrue = Method<bool>(key);

这样,一开始就无需在字典对象中跟踪 Type 值。

【讨论】:

我意识到 OP 使用了boolean,但在 C# 中它是 boolBoolean 同样来自 OP,Var 在 C# 中无效,应为 var Var 是我用来存储从文件中读取的内容的类的名称,我在整个 bool/boolean/Boolean 事物上松散地从内存中获取。 dynamic 关键字有效,但我只记得我仅限于 .3.5 框架,而 dynamic 仅限 4.0。 @FreeRadical:嗯,我给了你三个单独的选项,其中只有一个使用动态,所以如果有其他原因不适合你,请告诉我。而且,顺便说一句,将一个类命名为 Var 是一个非常糟糕的主意。【参考方案3】:

必须输入函数的返回类型。与任何其他变量或操作一样,从指定类型继承的任何类型都是有效的返回值(这就是 object 允许任何值作为值的原因)。

我个人认为创建一种具有多种返回类型的方法没有用,但如果您真的想要一种具有多种返回类型的方法,您可以在 .NET 4.0 中使用 dynamic 类型:

    private static void Main(string[] args)
    
        int x = Method("varName3");
        string word = Method("varName2");
        bool isTrue = Method("varName1");
    

    private static dynamic Method(string key)
    
        var dictionary = new Dictionary<string, KeyValuePair<Type, object>>()
        
             "varName1", new KeyValuePair<Type, object>(typeof(bool), false) ,
             "varName2", new KeyValuePair<Type, object>(typeof(string), "str") ,
             "varName3", new KeyValuePair<Type, object>(typeof(int), 5) ,
        ;

        if (dictionary.ContainsKey(key))
        
            return dictionary[key].Value;
        

        return null;
    

希望对你有帮助

【讨论】:

帮助很大,但不幸的是我仅限于 3.5 框架。背景:这是一个供使用 Unity 的人使用的工具。 如果您仅限于 .NET 3.5,我会尝试将方法设为通用:int x = Method("varName3");请看一下 StriplingWarrior 的回答。 喜欢 C# 如何让事物既是静态的又是动态的。

以上是关于具有多种返回类型的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在返回多种类型的方法中注入返回类型?

使用多种泛型类型在 Java 中实现抽象泛型方法

TypeScript 具有相同参数的多种返回类型

如何返回具有多种类型的对象

具有严格接口但弱类型的代码的术语

目标 C:如何在方法具有返回类型的方法中或在具有任何返回类型的覆盖方法中设置 NSAutoreleasePool?