【问题标题】:Declare a function supporting both Void and IEnumerator声明一个同时支持 Void 和 IEnumerator 的函数
【发布时间】:2012-03-16 05:45:01
【问题描述】:

我想知道是否有一种方法可以声明一个方法(例如在接口中),支持使用 IEnumerator 和 Void,而无需在子类中实现这两者?

public void Start()
public IEnumerator Start()

这与我的另一个问题有关: Hold or Wait while Coroutine finishes

我注意到在 Unity 上下文中,默认的 Start() 方法似乎允许两者。

【问题讨论】:

  • 请不要在你的标题前加上“C#:”之类的前缀。这就是标签的用途。
  • 为什么需要“void”版本?只是不使用结果就很好......
  • 对不起前缀...认为它会澄清/使我的问题更具体。在我的另一个问题中,我想要一个通用的 void 函数来调用协程并等待协程完成后再继续。

标签: c# void ienumerator


【解决方案1】:

您不能这样做,因为这些方法将具有相同的签名,并且 CSC 无法确定每个调用应该静态绑定哪个方法。例如:

public class TestClass
{
    public int FooMethod()
    {
        return 1;
    }
    public void FooMethod()
    {
        return;
    }
    public string FooMethod()
    {
        return "foo";
    }
}

static void Main()
{
    TestClass test = new TestClass();

    Console.WriteLine(test.FooMethod()); // which FooMethod should be called here?
}

方法的返回类型不被视为其签名的一部分。您可以做的是用不同的签名重载相同的方法以返回不同的类型。此外,对于仅返回void 不同的附加方法,您始终可以选择不使用原始方法返回的结果。

接口的情况类似。当一个类实现一个接口时,它同意一个协议,它实现了该接口的行为,这是您的类的消费者所期望的。所以你不能部分同意一个接口。尽管您可以在实现中抛出NotImplementedException,但您至少必须define所有成员,这会导致上面示例中提到的相同问题:C# 编译器将无法静态绑定您的方法调用,您的代码将无法编译。

您可以通过重新考虑您的设计来解决您的问题。

【讨论】:

  • 我理解编译器在确定哪个函数时存在歧义。我试图避免强制实现接口的类必须编写一个空函数。我似乎想不出一个通用的重新设计来让我在引用问题中做我需要的事情(等待 IEnumerator 函数完成)
  • 如果你很好地实现了你的方法,它不会做任何事情,直到引用者遍历 IEnumerator。因此,该方法将与想象中的 void 方法一样快。
【解决方案2】:

简短的回答是否定的。

最接近这一点的方法是使用泛型,但是这对于 void 无效,抱歉。

public T Start()

【讨论】:

    【解决方案3】:

    一个函数名+参数组合只能声明一次,因此只能有一个输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-05
      • 2012-12-02
      • 2012-10-17
      • 2015-11-13
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多