如何从C#partial方法返回值?

时间:2011-01-31 23:28:34

标签: c# .net

有没有办法这样做,因为似乎部分方法必须返回void(我真的不明白这个限制,但让它成为)?

6 个答案:

答案 0 :(得分:10)

嗯,从技术上讲,你可以从部分方法“返回”一个值,但它必须通过ref参数,所以它很尴尬:

partial void Foo(ref int result);

partial void Foo(ref int result)
{
    result = 42;
}

public void Test()
{
    int i = 0;
    Foo(ref i);
    // 'i' is 42.
}

在该示例中,如果i未实现,则Foo()的值不会更改。

答案 1 :(得分:8)

来自MSDN

  
      
  • 部分方法声明必须以contextual关键字partial开头,方法必须返回void。

  •   
  • 部分方法可以有参考但不能输出参数。

  •   

所以答案是不,你不能。

也许如果你更多地解释一下你的情况(为什么你需要返回一个值,为什么这个类是部分的),我们可以提供一个解决方法。

答案 2 :(得分:5)

您无法从部分方法返回值。

部分方法可能会也可能不会实施。如果允许从这样的方法返回一个值,那么调用者会收到什么?

答案 3 :(得分:4)

限制的原因是来自MSDN的这一行:

  

可能包含部分类或结构   部分方法。一部分   class包含了签名   方法。可选的实现可以   在同一部分或另一部分中定义   部分。 如果实施不是   提供,然后方法和所有   对该方法的调用将被删除   编译时间。 - 强调我的

如果该方法可能无法实施且可以删除。如果删除呼叫,其返回值会发生什么变化?

关于你的工作问题,这取决于你想要做什么,但显然你不能使用部分方法。

答案 4 :(得分:1)

喔。有一次我必须在我的一个项目中这样做。 您可以在名为ReturnValueException的方法中抛出异常,该异常定义为具有名为ReturnedValue的对象属性的异常。现在,您可以在Foo()块中调用方法try,并在catch块中收集结果。

不......开玩笑吧。

不要那样做。如初。

答案 5 :(得分:0)

这是一种技术,它依赖于扩展方法将被类方法屏蔽的事实。

ref参数技术相比,它涉及更多且不够清晰,因此我将使用它。

可以改用C#中的几种屏蔽机制:using static vs.方法,仅包含默认行为的父类与new方法,接受伪object的方法与参数类型更具体的方法等。

扩展方法或类方法(如果存在)之间的选择是在编译时进行的(即,它不使用后期绑定)。如果未密封部分类,则可能会导致一些问题:如果用实现也是可自定义的实现覆盖了可自定义方法,则需要使用新的接口和扩展方法

https://repl.it/@suzannesoy/WorthwhileSplendidBotany#main.cs

// On the auto-generated side:

interface IDefaultFoo { int DefaultFoo(); }

static class DefaultFoo {
  public static int CustomFoo(this IDefaultFoo o) => o.DefaultFoo();
}

partial class PartialClass : IDefaultFoo {
  int IDefaultFoo.DefaultFoo() => 42;
  // mark as virtual if you want to override in subclasses too.
  public virtual int Foo() => this.CustomFoo();
}

// On the user side:

partial class PartialClass {
  // Define this method only if you want to change
  // the default implementation of Foo.
  public int CustomFoo() => 123;
}

// In subclasses use override on the Foo method as usual
class SubClass1 : PartialClass {
  public new int CustomFoo() => 666; // This is not used
  public override int Foo() => 999;  // Use this instead
}

// If you also want to override in the subclass with a method which
// is also customizable, i.e. to provide a new default behaviour in
// the partial subclass that could also be customized, you'll need
// to add a new interface etc. otherwise the CustomFoo from the
// parent class would be called because it still shadows the
// extension method.
interface IDefaultFooSub2 { int DefaultFoo(); }
static class DefaultFooSub2 {
  public static int CustomFooSub2(this IDefaultFooSub2 o) => o.DefaultFoo();
}
partial class SubClass2 : PartialClass, IDefaultFooSub2 {
  int IDefaultFooSub2.DefaultFoo() => 1000000;
  public override int Foo() => this.CustomFooSub2();
}

class MainClass {
  public static void Main (string[] args) {
    System.Console.WriteLine(new PartialClass().Foo()); // 123
    System.Console.WriteLine(new SubClass1().Foo()); // 999
    System.Console.WriteLine(new SubClass2().Foo()); // 1000000
    System.Console.WriteLine(((PartialClass)new SubClass2()).Foo()); // 1000000
  }
}