Error in line : public virtual void BuyFavoriteStuff()
Error : Expected class, delegate, enm, interface, or struct
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LearnAbstractClass
{
class Program
{
static void Main(string[] args)
{
}
}
class Shopper
{
private int TotalSpent=0, CreditLimit=10;
public void ShopTillYouDrop()
{
while (TotalSpent < CreditLimit)
BuyFavoriteStuff();
}
}
public virtual void BuyFavoriteStuff()
{
// No implementation here - we don’t know
// what our student likes to buy!
}
class ArtStudent : Shopper
{
public override void BuyFavoriteStuff()
{
BuyArtSupplies();
BuyBlackTurtlenecks();
BuyDepressingMusic();
}
private void BuyBlackTurtlenecks()
{}
private void BuyDepressingMusic()
{}
private void BuyArtSupplies()
{}
}
class EngineeringStudent : Shopper
{
public override void BuyFavoriteStuff()
{
BuyPencils();
BuyGraphingCalculator();
BuyPocketProtector();
}
private void BuyPencils()
{}
private void BuyGraphingCalculator()
{}
private void BuyPocketProtector()
{}
}
}
What is the wrong in implementation above?
your method:
public virtual void BuyFavoriteStuff()
{
// No implementation here - we don’t know
// what our student likes to buy!
}
it outside of the Shopper class
You have method that is outside of any class:
public virtual void BuyFavoriteStuff()
{
// No implementation here - we don’t know
// what our student likes to buy!
}
just move it to Shopper class.
The method BuyFavoriteStuff is not inside class
public virtual void BuyFavoriteStuff()
{
// No implementation here - we don’t know
// what our student likes to buy!
}
You should declare your method inside class.
Related
I create child objects (Customer, Product, ...) and invoke method ApplyChange in parent class (AggregateRoot), from that method I would like to call method Apply in child class for passed event. Is it possible using reflection or I should change something?
public abstract class AggregateRoot
{
public void ApplyChange(IEvent #event)
{
Apply(#event); // how to call this method?
}
}
public class Customer : AggregateRoot
{
private void Apply(CustomerCreatedEvent e)
{
Console.WriteLine("CustomerCreatedEvent");
}
}
public class Product : AggregateRoot
{
private void Apply(ProductCreatedEvent e)
{
Console.WriteLine("ProductCreatedEvent");
}
}
public interface IEvent
{
}
public class CustomerCreatedEvent : IEvent
{
}
public class ProductCreatedEvent : IEvent
{
}
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer();
customer.ApplyChange(new CustomerCreatedEvent());
Product product = new Product();
product.ApplyChange(new ProductCreatedEvent());
}
}
Is it possible using reflection or I should change something?
I focused for now on the non-reflection, as IMO reflection should be the last resort here.
Option 1: abstract method
You could make Apply an abstract method en then you could call it from AggregateRoot.
e.g.
using System;
public abstract class AggregateRoot
{
public void ApplyChange(IEvent #event)
{
Apply(#event); // how to call this method?
}
protected abstract void Apply(IEvent e);
}
public class Customer : AggregateRoot
{
protected override void Apply(IEvent e)
{
if (e is CustomerCreatedEvent)
{
Console.WriteLine("CustomerCreatedEvent");
}
}
}
public class Product : AggregateRoot
{
protected override void Apply(IEvent e)
{
if (e is ProductCreatedEvent)
{
Console.WriteLine("ProductCreatedEvent");
}
}
}
public interface IEvent
{
}
public class CustomerCreatedEvent : IEvent
{
}
public class ProductCreatedEvent : IEvent
{
}
But please note, it has it downsides as:
methods needs to non-private
the should have the same parameter type for Apply. (IEvent parameter) - so I've added the type check inside the Apply methods.
Option 2: abstract method and generic AggregateRoot
Another option is to make AggregateRoot generic for the type IEvent, e.g. something like this.
using System;
public abstract class AggregateRoot<TEvent>
where TEvent : IEvent
{
public void ApplyChange(TEvent #event)
{
Apply(#event); // how to call this method?
}
protected abstract void Apply(TEvent e);
}
public class Customer : AggregateRoot<CustomerCreatedEvent>
{
protected override void Apply(CustomerCreatedEvent e)
{
Console.WriteLine("CustomerCreatedEvent");
}
}
public class Product : AggregateRoot<ProductCreatedEvent>
{
protected override void Apply(ProductCreatedEvent e)
{
Console.WriteLine("ProductCreatedEvent");
}
}
public interface IEvent
{
}
public class CustomerCreatedEvent : IEvent
{
}
public class ProductCreatedEvent : IEvent
{
}
Note I've changed also ApplyChange in this case.
If those things won't solve your problem, please elaborate what you are trying to archive, otherwise this will be a XY problem
I have a base class implementing an interface and further a specialized class inheriting the base class.
I have implemented interface's method in base class and marked it as virtual, also overridden the same method in specialized class.
Now i want to resolve the method GetData() on some basis that it either returns base class's method or child class's method.
So basically how can I call base class method using the specialized class's reference or interface's reference?
Edit 1
I have an existing data provider and I want to keep its functionality as it is and want to use some subclass or wrapper class where i can write a new implementation(another provider), mind that I want to keep running existing provider as it is for existing scenario and the new provider for other scenarios). what if i use decorator pattern to solve this? Any other pattern which can solve this ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
Console.ReadLine();
}
}
}
This is the only solution I could come up with for your problem:
interface IDataProvider
{
void GetData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
if (dataprovider is ManagedDataProvider)
{
(dataprovider as ManagedDataProvider).GetBaseData();
}
Console.ReadLine();
}
}
Another Way to attack it is adding GetBaseData to the Interface.
interface IDataProvider
{
void GetData();
void GetBaseData();
}
abstract class StandardDataProvider : IDataProvider
{
public virtual void GetData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
public virtual void GetBaseData()
{
Console.WriteLine("GetData_StandardDataProvider");
}
}
class ManagedDataProvider : StandardDataProvider
{
public override void GetData()
{
Console.WriteLine("GetData_ManagedDataProvider");
}
public override void GetBaseData()
{
base.GetData();
}
}
class Program
{
static void Main(string[] args)
{
IDataProvider dataprovider = new ManagedDataProvider();
dataprovider.GetData();
dataprovider.GetBaseData();
Console.ReadLine();
}
}
public class A
{
private void MethodA(){}
}
public class B
{
private void MethodB() { }
}
public class C
{
private void MethodC() { }
}
I want to make sure that MethodA can be called only from MethodB. Other method can never call MethodA.
Make MethodA protected and use inheritance like this:
public class A
{
protected void MethodA()
{
}
}
public class B : A
{
private void MethodB()
{
//MethodA is accessible just here
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
But if you don't want to use inheritance and want all the classes in the same assembly you could only nest class B within class A and keep MethodA private. Like this:
public class A
{
private void MethodA()
{
}
public class B
{
private void MethodB()
{
A a = new A();
a.MethodA();
}
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
public class D : A
{
private void MethodC()
{
//MethodA is not accessible here
}
}
I note that S.Akbari's answer, though good, does not exactly meet your requirement. You said that you wanted MethodA to be callable only within B, but in their answer, MethodA is callable within A.
The solution to the problem you actually posed is to invert the nesting:
class B
{
private class A
{
public void MethodA() { }
}
}
Now MethodA can only be called from within B.
But the question is bizarre. If you have a method that can only be called from B then why is it not a member of B?
We have an exercise about inheritance in c#. Now my problem is that what will i put in the question mark and in the if statement to know that the program passed a Person class or an Animal class or any class under InventoryApplication namespace. :)
private void AddButton_Click(object sender, EventArgs e)
{
Logic_Layer.Logic logic = new Logic();
//logic.Add<Person>();
}
namespace Logic_Layer
{
public class Logic
{
public void Add<InventoryApplication>() where InventoryApplication : ?
{
//if { }
}
public void delete() { }
public void edit() { }
public void search() { }
public void searchAll() { }
}
}
You can't use such a statement in the constraint. However, later in the method you can do this:
if (typeof(myObject).Namespace == "InventoryApplication")
{
...
}
What would be better is if the classes you want to test for (Animal, Person etc.) would implement an interface (say, IMyInterface).
For example:
void Add<T>(<T> param) where T : IMyInterface {/*...*/}
The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?