If I had this code:
public virtual void Foo()
{
void Bar()
{
// do important stuff for Foo
}
}
// In a child class:
public override void Foo()
{
Bar(); // Doesn't work
base.Bar(); // Also doesn't work
}
Is there anyway to call the local function defined in Bar inside of Foo without making Bar a normal method?
Is there anyway to call the local function defined in Bar inside of Foo without making Bar a normal method?
There is no by-design way. That's what "local" means. A local is accessible by name only by code in the location of the declaration; that's why they're called "locals".
Is there "any" way? Sure, you could do all kinds of shenanigans with reflection and decompilation and unsafe code and so on. Please don't. Those are implementation details of the compiler; don't try to reverse-engineer them and certainly do not rely on any implementation choice the compiler team has made being permanent!
Yes, you can pass around a delegate to it just as you do with any lambda expression. And no, this doesn't break any "rules," and we do it in Javascript all the time, under the module pattern, or whatever it's called.
public class MyBase
{
protected Action Foo()
{
return Local;
void Local()
{
Console.WriteLine("Hello world");
}
}
}
public class MyDerived : MyBase
{
public void HelloWorld()
{
var f = Foo();
f();
}
}
public class Program
{
public static void Main()
{
var o = new MyDerived();
o.HelloWorld();
}
}
Output:
Hello world
Link to DotNetFiddle
Related
I have a class A with a static method, and a derived class B. You can call Foo(), declared in A, on both A and B:
public class A
{
public static void Foo()
{
// How to get typeof(B) here if Foo called by using class B?
}
}
public class B : A
{
}
...
static class Program
{
static void Main()
{
B.Foo();
}
}
Now inside Foo(), how can I find out on which type Foo() was called?
I can't use keyword this, because I do not create any objects here. I have tried already:
MethodBase.GetCurrentMethod().DeclaringType
and
MethodBase.GetCurrentMethod().ReflectedType
but they both return me the typeof(A), while I need to get the typeof(B).
I'm not sure exactly what you want to achieve, and agree with the comments that perhaps you can approach this a different way. Saying this, could you do what you need with a generic base class?
public class AB<T>
{
public static void Foo()
{
Console.WriteLine(typeof(T));
}
}
public class A : AB<A> { }
public class B : AB<B> { }
A.Foo(); // A
B.Foo(); // B
There are no way to obtain typeof(B) inside of static method Foo() in this case. The possible solution is to use parameters in Foo method.
Thanks to #Jon Skeet and #CodeCaster.
I've never encountered this issue before today and was wondering what convention/best practice for accomplish this kind of behavior would be.
Basic setup is this:
public interface IDispatch {
void Dispatch();
}
public class Foo : IDispatch {
void IDispatch.Dispatch() {
DoSomething();
}
}
public class Bar : Foo {
...
}
Bar needs to subclass Foo because it shares all the same properties as Bar plus introduces 2 new ones that I need to encounter for. The problem I have is that Foo also needs a slightly different implementation of Dispatch(). Normally it would be overridden but thats not valid for an interface method so is it fine to just have Bar implement IDispatch as well so my class definition looks like this:
public class Bar : Foo, IDispatch { .... }
and then just do an explicit implementation of that interface method in Bar as well? My compiler doesn't seem to complain when I try to do it this way but I wasn't sure if it would cause any runtime issues resolving which implementation to use down the road or if there was a better way to accomplish something like this.
Also worth mentioning that at my workplace we use code generation from UML models which enforces that all class design must be done from a model first. The code generation tool is what causes interface methods to be implemented explicitly (don't want to debate the pros and cons of this its just what I'm forced to deal with right now so having an implicit implementation is not an option)
You could, alternatively, do this one of two ways:
First, don't implement the interface explicitly:
public class Foo : IDispatch {
public virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
public override void Dispatch() {
whateverElse();
}
}
Second, implement it explicitly but add a function that the child class can override:
public class Foo : IDispatch {
void IDispatch.Dispatch() {
this.Dispatch();
}
protected virtual void Dispatch() {
whatever();
}
}
public class Bar : Foo {
protected override void Dispatch() {
whateverElse();
}
}
Yes, you can explicitly redeclare that you want to implement IDispatch, and implement it explicitly again in Bar.
However, you won't be able to call the original implementation in Foo. If you need to do that, you'll need to change Foo either to use implicit interface implementation with a virtual method (which can be overridden and then called with base.Dispatch() in Bar) or make the Foo implementation call a protected virtual method which again you'd override in Bar.
Bar already implements IDispatch if it is subclass of Foo, no need to explicitly state that. If you want to implement only one method of interface in a different way, do sth like this:
IDispatch { void Method(); }
Foo : IDispatch { public virtual void Method() { implementation1 } }
Bar : Foo { public override void Method() { implementation2 } }
You don't have to do the IDispatch.Dispatch - so long as a method called Dispatch is in your class you will have implemented the interface.
You can do this, it builds for me:
public class Foo : IDispatch
{
public virtual void Dispatch()
{
}
}
public class Bar : Foo
{
public override void Dispatch()
{
base.Dispatch();
}
}
I do prefer to explicitly implement interfaces. It's easier for people unfamiliar with your code base to understand what's an interface vs class specific logic.
You can still accomplish class inheritance while explicitly implementing interfaces. You just need to have the base class implement the interface, and have that implementation call into a virtual function which can be extended. Here's an example:
interface Inter
{
void Call();
}
class A : Inter
{
//Explicitly implemented interface
void Inter.Call()
{
this.Call();
}
public virtual void Call() { Console.WriteLine("Base call in A"); }
}
class B : A
{
public override void Call()
{
Console.WriteLine( "Called B" );
}
}
class Program
{
static void Main( string[] args )
{
var a = new A(); //Base class
var aa = (Inter)a; //Interface only
a.Call();
aa.Call();
var b = new B(); //Child class
var bb = (Inter)b; //Interface only of Child class
b.Call();
bb.Call();
//See the output before the console program closes
Console.ReadLine();
}
}
Program output:
Base call in A
Base call in A
Called B
Called B
I'm relatively new to programming so excuse me if I get some terms wrong (I've learned the concepts, I just haven't actually used most of them).
Trouble: I currently have a class I'll call Bob its parent class is Cody, Cody has method call Foo(). I want Bob to have the Foo() method as well, except with a few extra lines of code. I've attempted to do Foo() : base(), however that doesn't seem to work like. Is there some simple solution to this?
You can override Foo in the derived class and call the overridden base class implementation using base.Foo():
class Cody
{
public virtual void Foo()
{
Console.WriteLine("Cody says: Hello World!");
}
}
class Bob : Cody
{
public override void Foo()
{
base.Foo();
Console.WriteLine("Bob says: Hello World!");
base.Foo();
}
}
Output of new Bob().Foo():
Cody says: Hello World!
Bob says: Hello World!
Cody says: Hello World!
Constructors use a slightly different syntax to call the constructor in a base class, because they have the requirement that the base class constructor must be called before the constructor in the derived class:
class Cody
{
public Cody()
{
}
}
class Bob : Cody
{
public Bob() : base()
{
}
}
The standard form (without polymorphism) is:
class Cody
{
public void Foo ()
{
}
}
class Bob : Cody
{
public new void Foo()
{
base.Foo(); // Cody.Foo()
// extra stuff
}
}
If you want polymorphism, the following 2 lines change:
// Cody
public virtual void Foo ()
// Bob
public override void Foo()
The difference shows when calling on a Bob instance through a Cody reference:
Bob b = new Bob();
Cody c = b;
b.Foo(); // always Bob.Foo()
c.Foo(); // when virtual, Bob.Foo(), else Cody.Foo()
You need to mark the base method as virtual, override it in the inherited class, and then call the base that way. You can either call the base before or after your code in the "Cody" class it is up to you on calling order.
class Bob
{
public virtual void Foo()
{
}
}
class Cody
{
public override void Foo()
{
base.Foo()
// your code
}
}
Today, I found something in legacy code. It has "static new" for one function. It looks like this.
class Foo
{
public static void Do()
{
Console.WriteLine("Foo.Do");
}
}
class Bar: Foo
{
public static new void Do()
{
Console.WriteLine("Bar.Do");
}
}
I don't understand the static new modifier for the Do method in class Bar. In C#, static method can only be invoked with class name instead of object name. So, I don't think there is any difference between having the "new" and not.
Generally, if some syntax is unnecessary, C# just treat it is error.
Anybody has any idea about why C# allows such syntax?
If you remove the new from your code you get:
warning CS0108: 'Bar.Do()' hides inherited member 'Foo.Do()'. Use the new keyword if hiding was intended.
The C# compiler just warns you that you might be doing something you did not intend and asks you to insert the new keyword to confirm that you know what you are doing. Besides suppressing the warning, it has no other effects.
That applies only for external callers. Remember that you can call a static method of the base class, so something like this is valid:
class Foo
{
public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
public static void Something()
{
Do();
}
}
This is why the warning tells you to put the new, you want to avoid any confusion when doing this:
class Foo
{
public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
public static void Something()
{
Do();
}
public static new void Do() { Console.WriteLine("Bar.Do"); }
}
have a look at this
public class BaseC
{
public static int x = 55;
public static int y = 22;
}
public class DerivedC : BaseC
{
// Hide field 'x'.
new public static int x = 100;
static void Main()
{
// Display the new value of x:
Console.WriteLine(x);
// Display the hidden value of x:
Console.WriteLine(BaseC.x);
// Display the unhidden member y:
Console.WriteLine(y);
}
}
/*
Output:
100
55
22
*/
Your example, to make it clear, should be
public class Foo
{
public static void Do() {}
}
public class Bar :Foo
{
public new static void Do() {}
}
In your example, the second class Bar doesn't seem to inherit from Foo. This seems to be a typo because it doesn't makes sense otherwise.
Assuming it to be a typo, the "new" modifier explicitly hides the base class version of the function Do(). This means that the derived version of the Do() method effectively replaces the base class version.
Using "new" here documents the fact that the inherited method is intended as a replacement for the base class version of Do().
For more information, see new Modifier (C#)
Coming from a C++ background, I've run into a snag with overloading based on a specific instance of a generic type. The following doesn't work since only once instance of the code for the Foo<T> class is ever generated, so inside the Method, the type of this is simply Foo<T>, not Foo<A> or Foo<B> as I'd hoped. In C++ I'm used to templates being instantiated as unique types.
using System.Collections.Generic;
class A
{
// Concrete class
}
class B
{
// Concrete class
}
class Bar
{
public void OverloadedMethod(Foo<A> a) {} // do some A related stuff
public void OverloadedMethod(Foo<B> b) {} // do some B related stuff
public void OverloadedMethod(OtherFoo of) {} // do some other stuff
public void VisitFoo(FooBase fb) { fb.Method(this); }
}
abstract class FooBase
{
public abstract void Method(Bar b);
}
class Foo<T> : FooBase
{
// Class that deals with As and Bs in an identical fashion.
public override void Method(Bar b)
{
// Doesn't compile here
b.OverloadedMethod(this);
}
}
class OtherFoo : FooBase
{
public override void Method(Bar b)
{
b.OverloadedMethod(this);
}
}
class Program
{
static void Main(string[] args)
{
List<FooBase> ListOfFoos = new List<FooBase>();
ListOfFoos.Add(new OtherFoo());
ListOfFoos.Add(new Foo<A>());
ListOfFoos.Add(new Foo<B>());
Bar b = new Bar();
foreach (FooBase fb in ListOfFoos)
b.VisitFoo(fb);
// Hopefully call each of the Bar::Overloaded methods
}
}
Is there a way to get something like this to work in C#? I'd rather not have to duplicate the code in Foo as separate classes for every type I want to use it for.
Edit:
Hopefully this is a little clearer.
I now have a genuinely complete piece of code which demonstrates the problem. Note to OP: please try compiling your code before posting it. There were a bunch of things I had to do to get this far. It's good to make it as easy as possible for other people to help you. I've also removed a bunch of extraneous bits. OtherFoo isn't really relevant here, nor is FooBase.
class A {}
class B {}
class Bar
{
public static void OverloadedMethod(Foo<A> a) { }
public static void OverloadedMethod(Foo<B> b) { }
}
class Foo<T>
{
// Class that deals with As and Bs in an identical fashion.
public void Method()
{
// Doesn't compile here
Bar.OverloadedMethod(this);
}
}
Yes, this doesn't compile. What did you expect it to do, exactly? Bear in mind that the overload resolution is performed at compile time, not execution time. As fallen888 says, you could cast and call the appropriate overloaded method - but which of the two overloads would you expect the compiler to pick otherwise? What do you want it to do with Foo<string> instead of Foo<A> or Foo<B>?
This all goes to demonstrate that .NET generics are indeed significantly different from C++ templates, of course...
I haven't tried it but it seems you should be able to achieve what you want by making A & B visitable (e.g. with the acyclic visitor pattern).
This works for the static case. Dealing with instance functions would be a bit more complicated. This post from Jon Skeet might provide a reasonable way to deal with instance methods.
class Program
{
static void Main(string[] args)
{
var testA = new Foo<A>();
testA.Method();
var testB = new Foo<B>();
testB.Method();
Console.ReadLine();
var testString = new Foo<string>(); //Fails
testString.Method();
Console.ReadLine();
}
}
class A { }
class B { }
class Bar
{
public static void OverloadedMethod(Foo<A> a)
{
Console.WriteLine("A");
}
public static void OverloadedMethod(Foo<B> b)
{
Console.WriteLine("B");
}
}
class Foo<T>
{
static Foo()
{
overloaded = (Action<Foo<T>>)Delegate.CreateDelegate(typeof(Action<Foo<T>>), typeof(Bar).GetMethod("OverloadedMethod", new Type[] { typeof(Foo<T>) }));
}
public void Method()
{
overloaded(this);
}
private static readonly Action<Foo<T>> overloaded;
}
Edit: I'm not sure that you can complete this as you're attempting. I've tried all sorts of tricks to attempt to get this to work and can't get it to compile. The best I can do is to pull the method call outside of my Generic class. If your method call is outside, then you can specifically define what T is in the generic. However, inside the method, at compile time, the compiler doesn't know what T will be so it doesn't know which overloaded method to call. The only way I can see around this is to use a switch to determine the type of T and manually specify the overload to call.
The best I can do is this, which isn't quite what you're after, but it could be used to a similar effect:
class Stuff<T>
{
public T value { get; set; }
}
class Program
{
static void DummyFunc(Stuff<int> inst)
{
Console.WriteLine("Stuff<int>: {0}", inst.value.ToString());
}
static void DummyFunc(Stuff<string> inst)
{
Console.WriteLine("Stuff<string>: {0}", inst.value);
}
static void DummyFunc(int value)
{
Console.WriteLine("int: {0}", value.ToString());
}
static void DummyFunc(string value)
{
Console.WriteLine("string: {0}", value);
}
static void Main(string[] args)
{
var a = new Stuff<string>();
a.value = "HelloWorld";
var b = new Stuff<int>();
b.value = 1;
var c = "HelloWorld";
var d = 1;
DummyFunc(a);
DummyFunc(b);
DummyFunc(c);
DummyFunc(d);
}
}
and got output:
Stuff<string>: HelloWorld
Stuff<int>: 1
string: HelloWorld
int: 1
I've got four overloaded functions referencing two referencing generic classes (one for int and one for string) and two referencing regular types (one for int and one for string) and it all works okay... is this what you're after?
Edit: The problem doesn't seem to be with the calling of the overloaded methods, it has to do with your foreach which is trying to convert all items in the list to the same type as the first in order to reference the overloaded method. The first item that doesn't conform to that exact definition will cause your compile to fail.
I was hoping to find an easier way to do this but for now I'm going with this:
Replace Foo<T> class with these classes:
abstract class Foo<T> : FooBase
{
// Class that deals with As and Bs in an identical fashion.
}
class Foo_A : Foo<A>
{
public override void Method(Bar b)
{
b.OverloadedMethod(this);
}
}
class Foo_B : Foo<B>
{
public override void Method(Bar b)
{
// Doesn't compile here
b.OverloadedMethod(this);
}
}
And change the instantiations to
List<FooBase> ListOfFoos = new List<FooBase>();
ListOfFoos.Add(new OtherFoo());
ListOfFoos.Add(new Foo_A());
ListOfFoos.Add(new Foo_B());
This at least doesn't require dublicating the code in Foo<T>, and just requires me to forward the constructors.