I have base class that contain abstract method.
public abstract class ClassBase : IClassBase
{
protected ClassBase()
{
//// some code
}
protected ClassBase(XmlNode settings)
: this()
{
}
protected abstract void Init(XmlNode settings);
}
public class Class_A : ClassBase
{
public Class_A(XmlNode settings)
: this(settings)
{
Init(settings);
}
protected override void Init(XmlNode settings)
{
}
}
Is it ok to call the Init method from Class_A constructor ?
I try to do it and its run ok - but when the constructor is running the virtual tables are not ready yet and the abstract method are not ready as far as i know.
It's unclear exactly what code you meant, as the code you've given doesn't compile for a couple of reasons. Most importantly, did you actually mean to call Init from ClassBase rather than from Class_A? If not, it seems pointless making Init abstract. This answer assumes you did meant that.
Is it ok to call the Init method from Class_A constructor ?
It's valid - but it's not usually a good idea.
It's not a matter of the "virtual tables" no being created - that's fine, and it will execute Class_A.Init. An object is created as an instance of its eventual type immediately. The problem is that you're calling a method on the Class_A instance before its constructor has had a chance to execute. That means it may be in an unexpected state - normal preconditions may not hold, for example.
Example
public class Class_A : ClassBase
{
private readonly string text;
public Class_A(XmlNode settings, string text)
: base(settings) // Which calls Init(settings) as per intro paragraph
{
if (text == null)
{
throw new ArgumentNullException("text");
}
this.text = text;
}
protected override void Init(XmlNode settings)
{
// In here, text is still null... even though it can't be in any
// other method.
}
}
Just occasionally, it's the least worst solution, but in that case:
Really make sure there isn't a better solution
Document it very clearly
Avoid calling the method from anywhere else, as it's often odd to code an implementation which is appropriate in both "I'm half way through initialization" and "I'm fully initialized" states.
Related
Firstly, sorry for my English. I hope i can explain my problem.
I have class like this
public class CarCommandExecutorBase
{
protected readonly ICarCommand CarCommand;
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
}
Also i have class like this
public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
public CarStringCommandExecutor(Car car)
{
// this Constructor gives me an error.
}
public void ExecuteCommand(string commandObject)
{
}
}
Error message:
[![error][1]][1]
What's the reason and how can i fix it? Thanks.
Since the only constructor in CarCommandExecutorBase is defined like this
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
you have to pass an ICarCommand when creating an instance of CarCommandExecutorBase.
You have to provide an ICarCommand through the constructor of CarStringCommandExecutor, because when instantiating a derived type the base constructor(s) also get called.
See this answer for more detailed information about this: https://stackoverflow.com/a/1882778/8450550
You could do something like this to solve this error:
public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
...
public CarStringCommandExecutor(Car car, ICarCommand carCommand)
: base(carCommand) // base() points to the constructor of the base class
{
...
}
or maybe this
public class CarStringCommandExecutor : CarCommandExecutorBase, IStringCommand
{
...
public CarStringCommandExecutor(Car car)
: base(null) // passing null but be aware of NullReferenceExceptions
{
...
}
or you add another constructor to CarCommandExecutorBase which expects no arguments:
public class CarCommandExecutorBase
{
protected readonly ICarCommand CarCommand;
public CarCommandExecutorBase(ICarCommand carCommand)
{
CarCommand = carCommand;
}
// mark this constructor as protected, so only deriving types can call it
protected CarCommandExecutorBase()
{
}
}
Which solution works best in your case is up to you.
One of the things that isn't immediately apparent, thanks to "compiler magic", about a C# class is that every class has a constructor
It needs to be this way because it's a rule that object construction happens in a tree; you construct some class Z which inherits from Y which inherits from X which inherits from object, and Z's cosntructor invokes Y's invokes X's invokes object's, then they finish, in order of object, X, Y, Z and you have your nicely constructed thing - every constructor on the way up the tree had its chance to do its init and ready the object for use (the part of it that each constructor was responsible for)
Even classes that don't seem to have constructors, have constructors:
class X {
}
If you don't provide a constructor, C# provides one for you. You never see it in your source code; just imagine that in between reading the file and compiling it, the compiler inserts it for you. It takes no parameters, has no code, and does nothing other than call its base:
class X {
X():base() { } //C# invisibly writes this for you
}
If you provide a constructor but don't write the base... bit, C# puts base() in for you behind the scenes (and it always calls the no-argument base()) but critically it doesn't provide an empty constructor if you provided one already
This means if you have a class like:
class X{
X(string message){
...
}
}
Your class X has a constructor, so C# won't provide the empty one, so now anything that tries to construct your class must provide a string message:
X x = new X("hello");
If you now inherit from X, you might do one of 3 things (with Y):
class Y:X{
}
You don't add a constructor, C# adds one, but it just dumbly calls base(), which doesn't work because there is no constructor in X that takes no args:
class Y:X{
Y():base() { }
}
You add a constructor but leave off the base bit. C# adds it, again just literally as base() - this also doesn't work for the same reason
class Y:X{
Y(int myArg) //c# adds base() in here for you
{
...
}
}
You add a constructor that includes a call to base and because you know your base class only has a constructor with a string arg, you pass one:
class Y:X{
Y(int myArg) : base("hello")
{
...
}
}
So you're in scenario 2, and you either need to:
Add a no-arg constructor to the base class so that c#'s auto-inserted stuff works or,
Add a call to base(...) with a suitable argument, to stop C# from putting a base() in
I've left out access modifiers from code in this answer for clarity of demonstrating the essential point. Whether a constructor is accessible or not can also have a bearing on all this, but I deemed it out of scope
I have two function which have some common functionality (i.e. to make connection with service and close connection after calling). I made a method named "InvokeService" with parameter of Func in it.How can I get parameters of request in InvokeService? I mean I need to get the object value of request? You can clear be clear by my demo code given below:
public void Method1(){
InvokeService(()=> _service.getMathod1(request);
}
public void Method2(){
InvokeService(()=> _service.getMathod2(request);
}
public void InvokeService(Func<T> request){
//service open
//I need here a complete object of the request of Method2 and its parameters
request.Invoke();
//service close
}
If any thing ambiguous or not understandable feel free to ask me.
You may want to use the template method pattern:
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
In your case, you can have something like this:
public abstract class AbstractClass
{
protected abstract void PrimitiveOperation();
public void TemplateMethod()
{
// before common functionality
PrimitiveOperation();
// after common functionality
}
}
class ConcreteClassA : AbstractClass
{
protected override void PrimitiveOperation()
{
// your A logic
}
}
class ConcreteClassB : AbstractClass
{
protected override void PrimitiveOperation()
{
// your B logic
}
}
If you want to return something different for each concrete class or have a different parameter depending the concrete class, you can achieve that with generics. Let me know if that is the case.
It can be solve by using Reflection;
request.GetMethodInfo()
once again I'm here for help. I'm writing my first "real-like" application to practice what I learned and I am not sure about my approach. I'll try to explain it as best as my english allows me.
Application consist of base abstract class and three classes inherited from that base.
abstract class BaseClass
{
// Some stuff...
// This method is used in all classes. It gets whole adb output
// and returns it as a string for future formating
protected string ProcessAdbCommand(string command)
{
try
{
_processInfo.Arguments = command;
Process adbProcess = Process.Start(_processInfo);
adbProcess.WaitForExit();
return adbProcess.StandardOutput.ReadToEnd();
}
catch (Exception e)
{
WriteToLog(e.Message);
return null;
}
}
}
After ProcessAdbCommand returns output, I will call another method which handles output as needed. Principle is always the same - format output and make somethinkg usefull based on the output.
Now I'd like to make clear, that method responsible for output handling needs to be in every inherited class. But problem is that in very class it returns different value type (boolean, List of IDevice and strings)
I am struggling here. First I wanted to make it protected abstract. Somethink like
abstract class BaseClass
{
// Some stuff...
// Same as above
protected string ProcessAdbCommand(string command)
{
//Same as above
}
//Method which will be implemented in every inherited class differently
protected bool|List<IDevice>|string ProcessAdbOutput(string adbOutput)
{
//Method implementation
return bool|List<IDevice>|string
}
}
But as I discovered it is not possible to override return type. And because method will be always used only internally in classes, I do not see reason to "force" it using interfaces.
After some time I game up and decided to forget about forcing implementation in derived classes and simply write them as I need. But do you think it is "legal" approach? How would you solve problem like that in "real world" application? Is there something I am still missing or is my approach simply wrong? Thank you.
Struggling Greenhorn.
One possible approach would be to make the abstract base class generic and accept a T parameter, which can also be the output of your ProcessAdbOutput method. Then, you make the method abstract to make sure any derived type has to implement it:
public abstract class BaseClass<T>
{
protected string ProcessAdbCommand(string command)
{
return string.Empty;
}
public abstract T ProcessAdbOutput(string result);
}
public class DerivedClass : BaseClass<IList<IDevice>>
{
public override IList<IDevice> ProcessAdbOutput(string result)
{
return new List<IDevice>();
}
}
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.
Lets say I have this:
class A { }
class B : A { }
class C : B { }
class Foo
{
public void Bar(A target) { /* Some code. */ }
}
class AdvancedFoo : Foo
{
public void Bar(B target)
{
base.Bar(target);
// Some code.
}
}
sealed class SuperiorFoo : AdvancedFoo
{
public void Bar(C target)
{
base.Bar(target);
// Some code.
}
}
Which overload will be called if I run new SuperiorFoo().Bar(new C()) and why?
I'm guessing it will be called cascadely but I can't figure out why and if that behavior is guaranteed.
UPDATED
So, the base. works with both Foo and AdvancedFoo for SuperiorFoo, so which one will be called and why?
Edited my answer now that the question has been revised.
A quick trace shows the following:
Entering SuperiorFoo.Bar()
Entering AdvancedFoo.Bar()
Entering Foo.Bar()
Leaving Foo.Bar()
Leaving AdvancedFoo.Bar()
Leaving SuperiorFoo.Bar()
Lets talk through what happens:
SuperiorFoo.Bar() calls its base method. Since SF.Bar() inherits
from AdvancedFoo, its base method is AdvancedFoo.Bar().
AdvancedFoo.Bar() then calls its base, which is Foo.Bar() since
AdvancedFoo inherits from Foo().
The process flow does NOT jump from SF.Bar() to Foo.Bar() because you could potentially want behaviour from the intermediate class.
If we remove the method from AdvancedFoo, the traversal is slightly different. SuperFoo.Bar() will still call its base method, but since AdvancedFoo doesn't hide the Foo.Bar() method anymore, the logic will jump to the Foo.Bar() method.
It wil keep calling the Bar() method inside SuperiorFoo untill it crashes with a StackOverflowException. If you want to call the base method of Bar() (so the method inside AdvancedFoo), you'll need to use this:
base.Bar(target);
Edit:
Looks like the code in the original post was changed. What happens now is that SuperiorFoo's 'Bar' will call AdvancedFoo's 'Bar', which will call Foo's 'Bar', and after that the code will be terminated.
Although KingCronus basically pointed out you have an infinite loop. The Signature will try to first match based on the exact type of object to the appropriate method, then should go down from that...
class Foo
{
public void Bar(A target) { /* Some code. */ }
}
class AdvancedFoo : Foo
{
public void Bar(B target)
{
base.Bar( (A)target );
// continue with any other "B" based stuff
}
}
sealed class SuperiorFoo : AdvancedFoo
{
public void Bar(C target)
{
base.Bar( (B)target );
// continue with any other "C" based stuff
}
}
By typecasting to the "Other" type (ie: B or A), it will go up to the appropriate chain...