How can I add a protected virtual method in the "Component" class, so that it can be called from the "Composite"?
As an concrete example, look at the code below, and please tell me how to avoid the compiler error in DxCompositeShape.ComputeSize.
abstract class DxShape // this is the Component
{
public abstract void Paint();
protected abstract void ComputeSize();
}
class DxCompositeShape : DxShape // this is the Composite
{
public readonly IList<DxShape> Shapes = new List<DxShape>();
public override void Paint()
{
this.ComputeSize();
}
protected override void ComputeSize()
{
foreach (DxShape sh in Shapes)
{
sh.ComputeSize(); // compiler error CS1540
}
// and some other logic here
}
}
EDIT: I modified my sample, so I have ComputeSize instead of Init (people assume that Init can always be called in a constructor).
You can't. A protected member of a different object can only be invoked if the compiler can see that the object in question is of the same type as your current object. Basically, "protected" means "Derived classes can use this member in their own class.
The underlying issue here is that you want some privileged classes ("composites") to be able to call a method of foreign classes ("components") that the base class declares is only for use of derived classes in their own implementation.
You might want to make Init internal, if all composites are in the same package. Or maybe make a subclass of the component that all composites inherit, and make this particular class privileged to call Init on all components. In C++ you would do such a thing with friend declarations. In C#, careful use of internal access is probably the right solution.
Create a non-virtual function Initialise() in the base class that calls Init
eg:
abstract class DxShape
{
protected void Initialise()
{
Init();
}
protected abstract void Init();
//...
}
As pointed out in the comments below, Initialise must be made either public or static (only in C#), it may remain protected in C++.
In C++ you could then make Init private and only access it via calls to Initialise. See non-virtual interface http://en.wikipedia.org/wiki/Non-virtual_interface_pattern
Related
With those classes:
public abstract class T_BaseClass
{
public virtual void m_canvas()
{
Console.WriteLine("canvas method called from template.");
}
}
public class C_ChildT : T_BaseClass
{
public override void m_canvas()
{
base.m_canvas();
Console.WriteLine("canvas method called from child template.");
}
}
What is the differences between those two implementations?
Difference between
C_ChildT mychildclass = new C_ChildT();
and
T_BaseClass mychildclass1 = new C_ChildT();
mychildclass.m_canvas();
mychildclass1.m_canvas();
Hope it looks better M.Skeet.
Thank you for your answer.
Basically, you don't need a deep understanding of inheritance to work with it. The minimum, that you should know is that the last child of inheritance sequence methods is called, when you call any method on an object. Also you should know that variable type and object type are different things, and you can store an object of child types in a variable of parent type. So, in your example you have two variables with C_ChildT and T_BaseClass types. But both objects are C_ChildT type. So when you call m_canvas() on each of them, you will call the C_ChildT implementation of m_canvas() in both cases.
Under the hood, when you call a virtual method, your runtime evironment sees, that the method is marked with the virtual keyword, so it (runtime environment) starts looking for overrriding of this method in the most derived class. You can read more about it here.
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()
I have a warning at the bottom of my screen:
Warning 1 'WindowsFormsApplication2.EventControlDataSet.Events' hides
inherited member
'System.ComponentModel.MarshalByValueComponent.Events'. Use the new
keyword if hiding was intended. C:\Users\myComputer\Desktop\Event
Control\WindowsFormsApplication2\EventControlDataSet.Designer.cs 112 32 eventControl
If i double click on it, it comes up with:
public EventsDataTable Events {
get {
return this.tableEvents;
}
Can anyone tell me how to get rid of this?
Your class has a base class, and this base class also has a property (which is not virtual or abstract) called Events which is being overridden by your class. If you intend to override it put the "new" keyword after the public modifier. E.G.
public new EventsDataTable Events
{
..
}
If you don't wish to override it change your properties' name to something else.
#wdavo is correct. The same is also true for functions.
If you override a base function, like Update, then in your subclass you need:
new void Update()
{
//do stufff
}
Without the new at the start of the function decleration you will get the warning flag.
In the code below, Class A implements the interface IShow and implements its method ShowData. Class B inherits Class A. In order to use ShowData method in Class B, we have to use keyword new in the ShowData method in order to hide the base class Class A method and use override keyword in order to extend the method.
interface IShow
{
protected void ShowData();
}
class A : IShow
{
protected void ShowData()
{
Console.WriteLine("This is Class A");
}
}
class B : A
{
protected new void ShowData()
{
Console.WriteLine("This is Class B");
}
}
The parent function needs the virtual keyword, and the child function needs the override keyword in front of the function definition.
this warning also triggers when you have: x:Name="Name1" with Text="{Binding Name1}" the Same Property Name in same Element in your <Xaml> which can cause a serious conflict at a certain point when your binding process become more complex.
Got the following code
protected virtual void InternalChange(DomainEvent #event)
{
((dynamic) this).Apply(#event);
}
child objects implement the logic to handle events via a number of fields eg
protected Apply ( Message1 message)
{
}
protected Apply ( Message2 message)
{
}
however this gives an error saying its inaccessible. I tried virtual but no luck..
Any ideas ? .. hopefully without reflection like this method. ( eg http://blogs.msdn.com/b/davidebb/archive/2010/01/18/use-c-4-0-dynamic-to-drastically-simplify-your-private-reflection-code.aspx)
More information I can move the InternalChange to the child class but id rather not have the child doing the dispatch.
void Apply(AggregateRootHandlerThatMeetsConventionEvent domainEvent)
{
OnAggregateRootPrivateHandlerThatMeetsConventionCalled = true;
}
void Apply(AggregateRootPrivateHandlerThatMeetsConventionEvent domainEvent)
{
OnAggregateRootPrivateHandlerThatMeetsConventionCalled = true;
}
void Apply(AggregateRootProtectedHandlerThatMeetsConventionEvent domainEvent)
{
OnAggregateRootProtectedHandlerThatMeetsConventionCalled = true;
}
protected override void InternalChange(DomainEvent #event)
{
Apply(((dynamic)#event));
}
Edit for now i'm using this in the child ( and made the parent abstract) which works but its ugly id rather implementers not worry about the dispatch .
protected void Handle(DomainEvent message)
{
Handle ( (dynamic) message);
}
You should define your base class to have either abstract or virtual on the method signature, for instance.
protected abstract void Apply(Message1 message);
Use virtual if you want to define an implementation in your base class that doesn't have to (but can) be overridden in the child class.
In your subclass, you would override it as such:
protected override void Apply(Message1 message)
{
// code here
}
Also, in your example, the method InternalChange is trying to call Apply with an argument of type DomainEvent, however, in both your overloads for Apply, they accept either type of Message1 or Message2. If it did compile, you would get a run time error anyway because the .NET dynamic run time would not be able to find an appropriate method that matches the argument.
As for using dynamic, I think it is unnecessary for the problem at hand.
The logic is sort of... reversed. I don't understand one or two things: what class is calling apply, the base type or the child type? How the discerning of the child class to send the event to happens? Couldn't you render Apply virtual protected and leave it empty in the base class?
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.