有没有办法这样做,因为似乎部分方法必须返回void(我真的不明白这个限制,但让它成为)?
答案 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
}
}