多种返回类型的方法

时间:2016-01-14 20:04:00

标签: c# generics methods return

我已经查看了许多与此相似的问题,但没有一个真正涉及到我想要做的事情。我要做的是从外部源读取一个变量列表,其中还包括它们的数据类型到字符串数组中:

示例:

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);
boolean isTrue = Method(string key);

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

3 个答案:

答案 0 :(得分:10)

编译器无法区分您提供的三个方法调用,因为它们看起来都像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值。

答案 1 :(得分:5)

在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 :(得分:0)

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

我个人认为创建一个具有多个返回类型的方法是有用的,但是如果你真的想要一个具有多个返回类型的方法,那么可以在.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;
    }

希望有所帮助