封装可能会或可能不会 return 值的代码

Encapuslate code that might or might not return a value

假设我有一些代码要重用。这段代码具有 属性 ,它要么 return 是某些东西,要么它修改了一些数据但没有 return 任何东西。因此,我无法将其作为常用方法(return 类型 void 是错误的,因为它可能 return,并且任何 return 类型也是错误的,因为它可能不是return).

C# 是否以任何方式支持那种 "method",即允许以某种方式封装和重用这样一段代码?

下面是一个示例用例:

我有一个接口 ITree<T> 和许多 classes T 实现 ITree<T>.

interface ITree<T>
{
    public T Child;
    public bool Ignore;
}

我有很多方法将实现 ITree<T> 的某种类型 T 的对象作为参数,并将某些 class 作为 return 类型。 几乎所有这些方法都是这样的:

MyClass2 SomeMethod(MyClass1 input) // MyClass1 implements ITree<MyClass1>
{
    while (input.Ignore)
    {
        input = input.Child;
        if (input == null)
            return null;
    }

    ... // do MyClass1 specific stuff and finally return some instance of MyClass2
}

因为while循环到处都是一样的,所以我想把它封装成一个"method",像这样:

... WhileLoop<T>(ref ITree<T> input)
{ // can't specify return type because it might return null or nothing at all
    while (input.Ignore)
    {
        input = input.Child;
        if (input == null)
            return null;
    }
}

MyClass2 SomeMethod(MyClass1 input)
{
    WhileLoop(ref input);
        // either returns null or changes input so that input can be used below

    ... // do MyClass1 specific stuff and finally return some element of MyClass2
}

但是由于这个"method"可能是也可能不是return什么的,所以它不可能是通常意义上的方法。

我可能误解了这个问题,但是返回一个 bool 呢?

bool MoveToNextNonIgnoreChild<T>(ref ITree<T> input)
{
    while (input.Ignore)
    {
        input = input.Child;
        if (input == null)
            return false;
    }

    return true;
}

MyClass2 SomeMethod(MyClass1 input)
{
    if (!MoveToNextNonIgnoreChild(ref input)) return null;

    ... // do MyClass1 specific stuff and finally return some instance of MyClass2
}

函数的 "voidable return" 没有关键字。 C# 不支持,而且我认为任何语言都不支持,因为它会破坏封装(调用方法应该提前知道 return 值是什么以获得或不获得结果)。 您唯一的选择是,returning null,忽略函数的输出或创建一个具有输出参数的 void 方法。

如果我没有正确理解你的问题,你的界面 ITree<T> 实际上应该是这样的:

interface ITree<T>
{
    public ITree<T> Child;
    public bool Ignore;
}

尽管存在命名问题(它是一个链表而不是树),查找下一个非忽略子项(或原始输入,如果 Ignore 为假)的循环可能如下所示:

public static ITree<T> GetNextNonIgnoreChild(this ITree<T> input)
{
    while (input != null && input.Ignore) input = input.Child;
    return input;
}

用法:

MyClass2 SomeMethod(MyClass1 input) // MyClass1 implements ITree<MyClass1>
{
    input = input.GetNextNonIgnoreChild();
    if (input == null) return null;
    ... // do MyClass1 specific stuff and finally return some instance of MyClass2
}

老实说,这样写实际上根本没有节省多少代码;你不妨写:

MyClass2 SomeMethod(MyClass1 input) // MyClass1 implements ITree<MyClass1>
{
    while (input != null && input.Ignore) input = input.Child;
    if (input == null) return null;
    ... // do MyClass1 specific stuff and finally return some instance of MyClass2
}