user310291
user310291

Reputation: 38228

How to return value from C# partial method?

Is there a way to do so as it seems partial method must return void (I really don't understand this limitation but let it be) ?

Upvotes: 19

Views: 4353

Answers (5)

Suzanne Soy
Suzanne Soy

Reputation: 3244

Here's a technique relying on the fact that an extension method will be shadowed by a class method.

It's more involved and less clear than the ref parameter technique, so I'll use that instead.

Several shadowing mechanisms in C# could be used instead: using static vs. method, a parent class containing just the default behaviour vs. a new method, a method accepting a dummy object vs. a method with a more specific argument type etc.

The choice between the extension method or the class method when it is present is made at compile-time (that is, it doesn't use late binding). This can lead to some problems if your partial class is not sealed: if you override the customizable method with an implementation which is also customizable, you need to use a fresh interface and extension method

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
  }
}

Upvotes: 3

Frédéric Hamidi
Frédéric Hamidi

Reputation: 263067

Well, technically you can "return" a value from a partial method, but it has to be through a ref argument, so it's quite awkward:

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.
}

In that example, the value of i won't change if Foo() is not implemented.

Upvotes: 16

shf301
shf301

Reputation: 31404

The reason for the restriction is this line from MSDN:

A partial class or struct may contain a partial method. One part of the class contains the signature of the method. An optional implementation may be defined in the same part or another part. If the implementation is not supplied, then the method and all calls to the method are removed at compile time. -- Emphasis Mine

If the method may not be implemented and can be removed. What would happen to its return value if the call is removed?

As to your question of a work around, that depends on what you are trying to do, but obviously you can't use a partial method.

Upvotes: 4

John Saunders
John Saunders

Reputation: 161811

You cannot return a value from a partial method.

Partial methods may or may not be implemented. If it were permitted to return a value from such a method, then what would the caller receive?

Upvotes: 6

RPM1984
RPM1984

Reputation: 73123

From MSDN:

  • Partial method declarations must begin with the contextual keyword partial and the method must return void.

  • Partial methods can have ref but not out parameters.

So the answer is no, you can't.

Perhaps if you explain a bit more about your situation (why you need to return a value, why the class is partial), we can provide a workaround.

Upvotes: 8

Related Questions