如何从方法的switch语句返回indeterminate类型的值

时间:2015-05-29 15:03:24

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

我有以下开关声明:

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#中,该方法必须明确定义返回类型。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

动态

您可以使用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);
    }
}