【问题标题】:How to return a value of indeterminate type from a switch statement from a method如何从方法的 switch 语句中返回不确定类型的值
【发布时间】:2015-08-12 12:27:02
【问题描述】:

我有以下 switch 语句:

switch (SomeType)
{
    case SomeType.A:
        var data = (Type_1)SomeType.Data;
    case SomeType.B:
        var data = (Type_2)SomeType.Data;
    case SomeType.C:
        var data = (Type_3) SomeType.Data;
    case SomeType.D:
        var data = (Type_4) SomeType.Data;
    case SomeType.E:
        var data = (Type_5) SomeType.Data;
    case SomeType.F:
        var data = (Type_6) SomeType.Data;
}

我有两个问题:

一个是switch语句似乎将整个事物视为一个范围,因此我不能多次设置var data,我想我可以克服这个问题,因为这需要包装在一个返回值的方法中,所以我可以做类似return (Type_6) SomeType.Data;的事情。

第二个问题是如何将它包装在返回方法中?据我所知,在 C# 中,该方法必须显式定义返回类型。有什么想法吗?

【问题讨论】:

  • 什么是 SomeType?它是否共享一个通用接口?
  • 您到底想达到什么目的?到目前为止,这听起来像是一个糟糕的架构决策。
  • 您的类型是否具有派生自它们的公共基类或接口?
  • @DavidL SomeType 将是传递给函数的参数
  • @walther 我想把这个开关封装成一个函数并返回转换后的类型,(var data)因为转换永远不一样,我不知道如何写返回类型函数。

标签: c# switch-statement return return-value


【解决方案1】:

动态

你可以使用dynamic作为返回类型:

public dynamic GetData()
{
    dynamic data;
    switch (SomeType)
    {
        case SomeType.A:
            data = (Type_1)SomeType.Data;
        case SomeType.B:
            data = (Type_2)SomeType.Data;
        case SomeType.C:
            data = (Type_3) SomeType.Data;
        case SomeType.D:
            data = (Type_4) SomeType.Data;
        case SomeType.E:
            data = (Type_5) SomeType.Data;
        case SomeType.F:
            data = (Type_6) SomeType.Data;
        default: throw new NotSupportedException();
    }
    return data;
}

只需添加一些break 语句,否则将无法编译。

但动态是highly contagious - 如果您在一种方法中使用它,它可能会通过使用原始方法的所有方法传播。


重构架构

虽然动态是一种快速解决方案,但它并不是最好的解决方案,因为它已经被评论员指出。理想情况下,您应该尽可能地保留类型信息 - 它可以简化开发并减少出错的可能性。

您可以为所有可能的数据对象使用一些基类或接口:

    public interface IData
    {
        // Common properties and methods
    }

    public IData GetData()
    {
        return SomeData.Data;
    }

但这可能需要对您的架构进行大量重新考虑,如果不同的Data 类型差异太大,这可能会也可能不会。

访客模式

如果是这种情况,那么您可以查看Visitor Pattern,它处理您的数据必须以非常不同的方式处理的情况。它仍然需要与返回类型相同的基本接口,但现在看起来像:

public interface IData
{
    void Accept(IDataVisitor visitor);
}

public interface IDataVisitor
{
    void Visit(DataA data);
    void Visit(DataB data);
    void Visit(DataC data);
}

public class DataA : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataB : IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}
public class DataC :  IData { public void Accept(IDataVisitor visitor) {visitor.Visit(this);}}

public class ConsoleVisitor : IDataVisitor
{
    public void Visit(DataA data)
    {
        Console.WriteLine("A" + data);
    }

    public void Visit(DataB data)
    {
        Console.WriteLine("B" + data);
    }

    public void Visit(DataC data)
    {
        Console.WriteLine("C" + (data);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多