Why are these two methods not ambiguous? - c#

This is the signature for the Ok() method in ApiController:
protected internal virtual OkResult Ok();
And this is my method from my RestController class (which extends from ApiController):
// Note that I'm not overriding base method
protected IHttpActionResult Ok(string message = null);
Since OkResult implements IHttpActionResult, both of these methods can be called like this:
IHttpActionResult result = Ok();
In fact, that's what I'm doing in my application.
My class PersistenceRestController (which extends from RestController), has these lines of code:
protected override async Task<IHttpActionResult> Delete(Key id)
{
bool deleted = //... Attempts to delete entity
if(deleted) return Ok();
else return NotFound();
}
This compiles fine, and no warning is raised about method ambiguity. Why is that?
PersistenceRestController has also inherited the protected methods from ApiController so it should have both versions of Ok() (and it does).
At execution, the method executed is the one from my RestController.
How does the compiler know which method to run?

Jon Skeet answered a similar question (without the inheritance complication) here:
When the compiler has two otherwise-equal options to choose from, it will use an overload which doesn't need use any unsupplied optional parameters in preference to one that does...
In your case, however, the method from the RestController is being chosen because it's the more derived class. Jon does a good job of addressing the topic in detail in his book C# in Depth -- look at the inheritance section of that page, which essentially states that the compiler will prefer a method on the actual instance class before methods on less derived classes.

EDIT:
I am leaving my original answer for posterity because I think it lets you visualize things, but DO NOT BE CONFUSED! The compiler does not actually treat the optional parameter as syntactic sugar for an overridden method. It treats it as a single method with an optional parameter. Dusty's answer, mentioning that "the method from the RestController is being chosen because it's the more derived class," is correct.
ORIGINAL (With visible edits for correctness):
Because they are NOT ambiguous. In order to be ambiguous the methods need to have the same signature. The fact that the string message parameter has a default value of null effectively creates BEHAVES as though it creates two callable overrides, one of which HIDES the original method, and one of which is distinctly callable with a string.
You are effectively doing creating the same behavior as if you were to do this:
public class RestController : ApiController
{
protected new OkResult Ok()
{
return Ok(null);
}
protected OkResult Ok(string message)
{
// Do your thing...
}
}
You will find there is no way to directly call ApiController.Ok() from PersistenceRestController.
If you want to call ApiController.Ok() from RestController, you'll have to use the base keywoard: base.Ok();

While #DimitarTsonev and #Dusty are telling true stuffs, but your answer is something between their answers. Here, you have inheritance situation. See these classes:
public class Foo {
public void Bar() {
}
}
public class Foo2 : Foo{
public void Bar(string message = null) {
}
}
public class Foo3 : Foo2{
public void Test(){
Bar();
}
}
When you call Bar() in your Foo3 class, the runtime will lookup after the method inside the Foo3 class. If found it, execute it, otherwise go to the top class: Foo2 and look after Bar method. Is there any? yes! so execute it! that's why when you call Ok, your RestControllers' version get executed.
But also, the Foo2.Bar(string message = null) will not conflict with Foo.Bar() because they are NOT ambiguous as #DimitarTsonev said. So, your code will work just fine.
AND, what about calling Foo.Bar() from Foo3? You have to use casting here:
public class Foo3 : Foo2 {
public void Test() {
Bar(); // this will execute Foo2.Bar()
}
public void Test2() {
((Foo)this).Bar(); // this one will execute Foo.Bar()
}
}

public class Foo
{
public void Bar()
{
}
public void Bar(string message = null)
{
}
}
Those are two different methods because the second has the optional argument.
However, please note that the second method called with no arguments will actually execute the first one, which may produce some unexpected behaviour.

Related

NSubstitute ForPartsOf calling concrete implementation event when substituted

I have the following class:
public class MyClass : IMyClass
{
public string MyFunc(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new Exception("Blank Name");
}
return name;
}
public double MyFuncWrapper(string name)
{
var value = MyFunc(name);
return value;
}
In trying to test it, I was under the impression that NSubstitute's ForPartsOf effectively subclassed my class and replaced the flagged methods; so I did this:
[Fact]
public void TestMyFuncWrapper()
{
// Arrange
var myClass = Substitute.ForPartsOf<MyClass>();
myClass.MyFunc(Arg.Any<string>()).Returns("Test");
// Act
var result = myClass.MyFuncWrapper("");
// Assert
Assert.Equal("Test", result);
}
However, I get the exception raised from, what I understood to be, my substituted method. Oddly, it appears that the following line:
myClass.MyFunc(Arg.Any<string>()).Returns("Test");
Is actually calling the concrete function immediately. Looking here, it appeared that a construct like this may solve the problem (although it does use the phrase "playing it safe" which sounds quite vague):
myClass.When(a => a.MyFunc(Arg.Any<string>())).DoNotCallBase();
However, calling this actually invokes MyFunc immediately in the same way. Clearly I'd misunderstood the ForPartsOf method; my question is: can I do what I'm attempting using NSubstitute, or do I need to resort to manually subclassing MyClass?
This is by design for NSubstitute (and for most mocking frameworks).
The docs state:
For starters, NSubstitute can only work with virtual members of the
class, so any non-virtual code in the class will actually execute!
Thus, you need to add virtual to the function declarations you plan to mock.
Or (as per the docs):
If possible, stick to substituting interfaces.

C# Method Overload and Extension Methods [duplicate]

There have been occasions where I would want to override a method in a class with an extension method. Is there any way to do that in C#?
For example:
public static class StringExtension
{
public static int GetHashCode(this string inStr)
{
return MyHash(inStr);
}
}
A case where I've wanted to do this is to be able to store a hash of a string into a database and have that same value be used by all the classes that use the string class's hash (i.e. Dictionary, etc.) Since the built-in .NET hashing algorithm is not guaranteed to be compatible from one version of the framework to the next, I want to replace it with my own.
There are other cases I've run into where I'd want to override a class method with an extension method as well so it's not just specific to the string class or the GetHashCode method.
I know I could do this with subclassing off an existing class but it would be handy to be able to do it with an extension in a lot of cases.
No; an extension method never takes priority over an instance method with a suitable signature, and never participates in polymorphism (GetHashCode is a virtual method).
If the method has a different signature, then it can be done -- so in your case: no.
But otherwise you need to use inheritance to do what you are looking for.
As far as I know the answer is no, because an extension method is not an instance.It's more like an intellisense facility to me that let you call a static method using an instance of a class.
I think a solution to your problem can be an interceptor that intercepts the execution of a specific method (e.g. GetHashCode()) and do something else.To use such an interceptor (like the one Castle Project provides) all objects should be instansiated using an object factory (or an IoC container in Castle) so that thier interfaces can be intercepted through a dynamic proxy generated in runtime.(Caslte also lets you intercept virtual members of classes)
I have found a way to invoke an extension method with the same signature as a class method, however it does not seem very elegant. When playing around with extension methods I noticed some undocumented behavior. Sample code:
public static class TestableExtensions
{
public static string GetDesc(this ITestable ele)
{
return "Extension GetDesc";
}
public static void ValDesc(this ITestable ele, string choice)
{
if (choice == "ext def")
{
Console.WriteLine($"Base.Ext.Ext.GetDesc: {ele.GetDesc()}");
}
else if (choice == "ext base" && ele is BaseTest b)
{
Console.WriteLine($"Base.Ext.Base.GetDesc: {b.BaseFunc()}");
}
}
public static string ExtFunc(this ITestable ele)
{
return ele.GetDesc();
}
public static void ExtAction(this ITestable ele, string choice)
{
ele.ValDesc(choice);
}
}
public interface ITestable
{
}
public class BaseTest : ITestable
{
public string GetDesc()
{
return "Base GetDesc";
}
public void ValDesc(string choice)
{
if (choice == "")
{
Console.WriteLine($"Base.GetDesc: {GetDesc()}");
}
else if (choice == "ext")
{
Console.WriteLine($"Base.Ext.GetDesc: {this.ExtFunc()}");
}
else
{
this.ExtAction(choice);
}
}
public string BaseFunc()
{
return GetDesc();
}
}
What I noticed was that if I called a second method from inside an extension method, it would call the extension method that matched the signature even if there was a class method that also matched the signature. For example in the code above, when I call ExtFunc(), which in turn calls ele.GetDesc(), I get the return string "Extension GetDesc" instead of the string "Base GetDesc" that we would expect.
Testing the code:
var bt = new BaseTest();
bt.ValDesc("");
//Output is Base.GetDesc: Base GetDesc
bt.ValDesc("ext");
//Output is Base.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext def");
//Output is Base.Ext.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext base");
//Output is Base.Ext.Base.GetDesc: Base GetDesc
This allows you to bounce back and forth between class methods and extension methods at will, but requires the addition of duplicate "pass-through" methods to get you into the "scope" you desire. I am calling it scope here for lack of a better word. Hopefully someone can let me know what it is actually called.
You might have guessed by my "pass-through" method names that I also toyed with the idea of passing delegates to them in the hopes that a single method or two could act as a pass-through for multiple methods with the same signature. Unfortunately it was not to be as once the delegate was unpacked it always chose the class method over the extension method even from inside another extension method. "Scope" no longer mattered. I have not used Action and Func delegates very much though so maybe someone more experienced could figure that part out.

How to prevent shadowing and promote given method?

In C++ it is done with "using", and in C#?
public class foo
{
public void print(string s) {...}
}
public class bar : foo
{
// shadowing
public void print(object o) {...}
}
How to promote foo.print, so foo.print and bar.print would be at the same "level" for compiler (for bar of course)?
Update 1
Originally I added a paragraph about common confusion between shadowing and overriding, but then I deleted it, because I thought it will be offensive to readers.
Shadowing is like overloading spanned over inheritance tree. Shadowing is NOT overriding.
Update 2
After shadowing foo.print is no longer taken into account when resolving the overloaded method print. Promoting foo.print would get it back into process -- so when I call bar_object.print("hello") the method foo.print would be called.
In your concrete example, bar.print(object) indeed "shadows" the more specific foo.print(string):
new bar().print("i am a string");
This will call the method defined on bar, although the method on foo would have a parameter that matches the type better.
What happens here is the following: The compiler finds a method on bar with the right name ("print"), the right number of parameters (1) and a parameter type to which the passed in parameter is convertable to (string can be converted to object).
Because of this, there is no reason for the compiler to look further up the inheritance chain.
As far as I am aware, there is no construct similar to C++'s using.
If you want to use the method defined on the base class, you basically have three options:
On the caller side: Convert the bar instance to foo:
var bar = new bar();
var foo = (foo)bar;
foo.print("i am a string"); // Will call foo.print(string)
On the calee side: Inside bar.print(object) check the type of the passed parameter:
public void print(object o)
{
var s = o as string;
if(s != null)
base.print(s);
else
{
// Other code.
}
}
This will come the closest to the C++ using: Actually override or hide the original method in the derived class:
public class bar : foo
{
public new void print(string s)
{
base.print(s);
}
public void print(object o)
{
// some code
}
}

Declare a function supporting both Void and IEnumerator

I was wondering if there is a way to declare a method (in an interface for example) that supports the use of IEnumerator and Void, without the need to implement both in the subclasses?
public void Start()
public IEnumerator Start()
this is related to my other question: Hold or Wait while Coroutine finishes
i noticed in the Unity context, the default Start() method seems to allow for both.
You can't do that because those methods would have the same signature and the CSC woudn't be able to figure out which method should be statically bound for each call. e.g.:
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?
}
A method's return type is not considered as part of its signature. What you can do is overload the same method with a different signature to return a different type. Also, in the case of an additional method that differs only in returning void, you can always choose not to use the result returned by the original method.
The case with interfaces is similar. when a class implements an interface it is agreeing to a protocol, that it implements that interface's behaviour which is what consumers of your class expect. So you cannot partly agree with an interface. Although you can throw a NotImplementedException in your implementations you have to at least define all members, which leads to the same problem mentioned in the above example: the C# compiler will not be able to statically bind your method calls and your code will fail to compile.
You can solve your problem by reconsidering your design.
The short answer is no.
The closest you could get to this is using generics, however that would not work for a void, sorry.
public T Start()
One function name + combination of parameters can only be declared once, thus can only have one output.

How can I make a delegate refer to a specific version of a method?

I'd like to make a delegate that invokes a specific instance method, unfortunately, it seems that if the method is virtual, the override of the method for the inheriting class will be invoked rather than the base version.
public class Base{
public virtual void Method(){
Console.WriteLine("Base");
}
}
public class Child : Base{
public override void Method(){
Console.WriteLine("Child");
}
}
If somewhere else in the code I have the following::
var action = Delegate.CreateDelegate(typeof(Action<Base>), typeof(Base).GetMethod("Method")) as Action<Base>;
action(new Child());
The output of this program is Child. I'd really like it to be Base. I've tried the same thing with expression trees and I get the same result, as the IL emitted uses the callvirt method. Is the only way to do something like this really with Reflection.Emit?
The reason I ask is that I am using a type builder to override behavior of a class. If I were to write the method myself, I could just go base.Method() or whatever, but, some of the method behavior can only be determined dynamically at runtime, as accounting for the many possible cases would be very tedious.
Since i'm creating a class that derives from Base at runtime, if I try to invoke Method() inside the Method() overload I'm making it leads to infinite recursion and stack overflow exceptions. (not so good).
This is for an AOP style project where I'm adding some logic to the methods at runtime. I tag the methods with attributes, I then have a type builder that create methodBuilders feeding the body of the methodbuilder with an expression tree using the CompileToMethod(methodbuilder) http://msdn.microsoft.com/en-us/library/dd728224.aspx,
This is a ton easier than reflection.emit, as the logic is non-trivial that I am adding. The goal is than I have a factory spit out a new class that whenever I call Method() it does some logic first before ultimately calling the base implementation.
Yes, Reflection.Emit is the only way provided by the .NET framework to implement method overloads. Since the other APIs aren't used when overloading methods, they don't provide any way to chain to the base implementation.
Maybe you can use such a workaround:
public class Base{
public virtual void Method(){
MethodImpl();
}
public void MethodImpl(){
Console.WriteLine("Base");
}
}
public class Child : Base{
public override void Method(){
Console.WriteLine("Child");
}
}
Now, you can create a delegate representing MethodImpl.
What's suppose to happen here?
class Base { public abstract void Method(); }
class Child {
public override void Method() {
Console.WriteLine("Child.Method");
}
}
Action<Base> magicalAction = // defined somehow
magicalAction(new Child()); // aiya!
You're trying to defeat the point of virtual methods. Why?
Since Reflection.Emit is such a difficult way to build a whole method, I would recommend using Reflection.Emit to create private methods just for calling the base methods. Then you can refer to those methods from your Expressions.

Categories