I have a class named PINPAD, a base class named Devices, and two derived classes named DevA and Dev B
The issue is that the main class property PINPAD.Status needs to be updated from classes DevA and DevB
Here is the code:
public class CALLER()
{
CALLER()
{
PINPAD PINPD = new PINPAD("A");
//....
MessageBox.Show(PINPD.Status);
}
}
public class PINPAD()
{
public Devices MyDev = null;
public string Status = "";
public PINPAD(string Model)
{
if (Model = "A")
{
DevA MyDev = new DevA()
}
else
{
DevB MyDev = new DevB()
}
MyDev.DoWork();
}
}
public class Devices
{
public virtual void DoWork() {}
}
public class DevA : Devices
{
public override void DoWork() { }
DevA()
{
PINPAD.Status = "Broken";
//Status not avialable!
}
}
public class DevB : Devices
{
public override void DoWork() { }
DevB()
{
PINPAD.Status = "Working!";
//Status not avialable!
}
}
You've declared PINPAD.Status as an instance field - meaning you have to have an object of the type PINPAD in order to access it.
var myPinpad = new PINPAD();
myPinpad.Status = "Whatever";
If you want there to just be one field that is available everywhere, declare the field static:
public static string Status = "";
Related
Static class code :
static public class CommonValues
{
public static string _consumerName;
}
Assigning from a non-static class :
public class CreateSessionConsumer : IClassFixture<CommonFixture>
{
private IMockProviderService _mockProviderService;
private string _mockProviderServiceBaseUri;
public string _path = "/Security/CreateSession";
public CreateSessionConsumer(CommonFixture fixture)
{
Common.CommonValues._consumerName = "CreateSessionConsumer";
Common.CommonValues._providerName = "CreateSessionAPI";
_mockProviderService = fixture.MockProviderService;
_mockProviderService.ClearInteractions(); //NOTE: Clears any previously registered interactions before the test is run
_mockProviderServiceBaseUri = fixture.MockProviderServiceBaseUri;
CommonFixture.PactDirectory=#"..\pacts";
//CommonFixture.Provider=_provider;
}
}
Accessing in this static variable in a generic method:
public class CommonFixture : IDisposable
{
public IPactBuilder PactBuilder { get; private set; }
public IMockProviderService MockProviderService { get; private set; }
public int MockServerPort { get { return 9222; } }
public string MockProviderServiceBaseUri { get { return String.Format("http://localhost:{0}", MockServerPort); } }
public static string PactDirectory { get; set; }
public CommonFixture()
{
var pactConfig = new PactConfig
{
SpecificationVersion = "2.4.6",
PactDir = #"..\..\..\..\..\pacts",
LogDir = #".\pact_logs"
};
PactBuilder = new PactBuilder(pactConfig);
PactBuilder.ServiceConsumer(Common.CommonValues._consumerName)
.HasPactWith(Common.CommonValues._providerName);
MockProviderService = PactBuilder.MockService(MockServerPort);
}
}
Issue is, CreateSessionConsumer class is not assigning the static variable. And CommonFixture is accessing a unassigned variable.
This could not be handled the way I have asked here. Eventually had to implement Fixture class along with each class file, which sets the consumername and providername individually.
Please first take a look at this simple code;
This is my base class:
public class BaseClass
{
public BaseClass()
{
}
public BaseClass(BaseClass b)
{
}
public virtual string GetMSG()
{
return "Base";
}
}
and this is the derived one:
public class DrivenClass : BaseClass
{
public string MSG { get; set; }
public DrivenClass(string msg)
{
MSG = msg;
}
public DrivenClass(DrivenClass d)
{
MSG = d.MSG;
}
public override string GetMSG()
{
return MSG;
}
}
and this is the test:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public BaseClass B { get; set; }
public DrivenClass D { get; set; }
private void button1_Click(object sender, EventArgs e)
{
D = new DrivenClass("Driven");
B = new BaseClass(D);
MessageBox.Show("B:" + B.GetMSG() + "\nD:" + D.GetMSG());
}
}
Now my question is what should I do that B = new BaseClass(D); works like B = new DrivenClass(D); ?
I'm using this in polymorphism and I like to use one copy-constructor instead of different driven ones.
I want the output like this :
Driven
Driven
but now it's like this :
Base
Driven
You can use an overridden virtual Copy method instead of a copy constructor.
public class BaseClass
{
public BaseClass()
{
}
public virtual BaseClass ShallowCopy()
{
return new BaseClass();
}
public virtual string GetMSG()
{
return "Base";
}
}
public class DrivenClass : BaseClass
{
public string MSG { get; set; }
public DrivenClass(string msg)
{
MSG = msg;
}
public override BaseClass ShallowCopy() {
return new DrivenClass(this.MSG);
}
public override string GetMSG()
{
return MSG;
}
}
Then call it like this:
D = new DrivenClass("Driven");
B = D.ShallowCopy();
This will work because calling a virtual method always calls the actual overriden implementation in the subclass, even when called from the baseclass interface.
What happens is normal because you create new instance of base class here. Therefore you never override the GetMSG method:
B = new BaseClass(D);
What you wanted to do is to have the same public class:
public BaseClass B { get; set; }
and to give it the value of new DrivenClass(D)
B = new DrivenClass(D);
I am setting a property of base class from derived class as following:
public abstract class Coverter
{
public Mydata data { get; set; }
public abstract void Convert();
}
public class Mydata
{
public int i;
}
public class Coverter1 : Coverter
{
public Coverter1(Mydata data1)
{
data = data1;
}
public override void Convert()
{
Console.WriteLine(data.i.ToString());
}
}
private static void Main(string[] args)
{
Mydata data = new Mydata();
data.i = 5;
Coverter c = new Coverter1(data);
c.Convert();
Console.ReadLine();
}
Is there any flaw with this kind of implementation ? What could be the better approach?
I can do the same thing in the following approach.
public abstract class Coverter
{
public Mydata data { get; set; }
public abstract void Convert();
}
public class Mydata
{
public int i;
}
public class Coverter1:Coverter
{
override public void Convert()
{
Console.WriteLine(data.i.ToString());
}
}
static void Main(string[] args)
{
Mydata data1 = new Mydata();
data1.i = 5;
Coverter c = new Coverter1();
c.data = data1;
c.Convert();
Console.ReadLine();
}
Which appraoch is better?
Pass the field down in the constructor. (Note: normally you should name fields starting with a lower case character and properties with uppercase). Here is an example where I fixed the naming.
public abstract class Converter
{
private readonly MyData data;
protected Converter(MyData data)
{
this.data = data;
}
public MyData Data { get { return data; } }
}
public class MyData
{
private readonly int value;
public MyData(int value)
{
this.value = value;
}
public int MyValue { get { return value; } }
}
public class Converter1 : Converter
{
public Converter1()
: base(new MyData(5))
{
}
}
I recommend the practice of using readonly fields and getters only for properties to start with. Doing so will make your types immutable which usually helps get your program correct initially. Start off immutable and then introduce mutability where you need it, and only once you need it. Having the types immutable like this requires passing the values through the constructor.
I just did something kind of wacky using a partial class and I'm wondering if there's an already established pattern that might have accomplished the same thing using a less confusing approach.
The problem:
I had a base class with protected members and virtual methods designed for the derived class to do work when they are called.
I wanted to delegate this work out to a list of workers.
However I needed the workers to have access to the protected members.
My probably overly complicated solution:
Note: I realize this depends on the class being partial - I'm OK with that but it would be cool if there was a solution that didn't need it...
void Main()
{
ABase aBase = new ADerived();
aBase.DoWork();
}
public partial class ABase
{
protected int state1 = 1;
protected int state2 = 2;
List<ABase> workers;
public ABase()
{
workers = new List<ABase>();
CreateWorkers(workers);
}
protected virtual void CreateWorkers(List<ABase> workers)
{
}
public ABase(ABase aBase)
{
this.Target = aBase;
}
public virtual void DoWork()
{
foreach (var worker in this.workers)
{
worker.DoWork();
}
}
protected ABase Target { get; private set; }
}
public partial class ABase
{
public class Worker1 : ABase
{
public Worker1(ABase aBase) : base(aBase) { }
public override void DoWork()
{
Console.WriteLine (Target.state1);
}
}
public class Worker2 : ABase
{
public Worker2(ABase aBase) : base(aBase) { }
public override void DoWork()
{
Console.WriteLine (Target.state2);
}
}
}
public class ADerived : ABase
{
protected override void CreateWorkers(List<ABase> workers)
{
workers.Add(new Worker1(this));
workers.Add(new Worker2(this));
}
}
Output:
1
2
I would change the design so that the workers weren't accessing instance fields at all. I would have DoWork take a parameter with the information that they need and have the base class pass the state into the DoWork method.
public class MyState //TODO give better name
{
public int State1 { get; set; }
public int State2 { get; set; }
}
public class ABase
{
public MyState state = new MyState()
{
State1 = 1,
State2 = 2
};
List<Action<MyState>> workers = new List<Action<MyState>>();
public ABase()
{
CreateWorkers();
}
public void DoWork()
{
foreach (var action in workers)
{
action(state);
}
}
private void CreateWorkers()
{
workers.Add(new Worker1().DoWork);
workers.Add(Worker2.Process);
}
}
public class Worker1
{
public void DoWork(MyState state)
{
Console.WriteLine(state.State1);
}
}
public class Worker2
{
public static void Process(MyState state)
{
Console.WriteLine(state.State2);
}
}
I have the following C# code. Here the validations are kept outside the class to satisfy Open – Closed Principle. This is working fine. But the challenge is – the validations are not generic. It is specific to employee class (E.g DateOfBirthRuleForEmployee). How do I make the validations generic for all objects (DateOfBirthRuleForAnyObject).
Note: Make Generic <==> Make Type-Independent
Note: I have NameLengthRuleForEmployee validation also. New validation may come in future.
EDIT
Generic Method Example: Using “OfType” in LINQ
CODE
class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
employee.DateOfBirth = DateTime.Now;
employee.Name = "Lijo";
DateOfBirthRuleForEmployee dobRule = new
DateOfBirthRuleForEmployee();
NameLengthRuleForEmployee nameRule = new
NameLengthRuleForEmployee();
EmployeeManager employeeManager = new EmployeeManager();
employeeManager.AddRules(dobRule);
employeeManager.AddRules(nameRule);
bool result = employeeManager.validateEntity(employee);
Console.WriteLine(result);
Console.ReadLine();
}
}
public interface IEntity
{
}
public interface IRule<TEntity>
{
bool IsValid(TEntity entity);
}
public class DateOfBirthRuleForEmployee : IRule<Employee>
{
public bool IsValid(Employee entity)
{
return (entity.DateOfBirth.Year <= 1975);
}
}
public class NameLengthRuleForEmployee : IRule<Employee>
{
public bool IsValid(Employee employee)
{
return (employee.Name.Length < 5);
}
}
public class Employee : IEntity
{
private DateTime dateOfBirth;
private string name;
public DateTime DateOfBirth
{
get
{
return dateOfBirth;
}
set
{
dateOfBirth = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
public class EmployeeManager
{
RulesEngine<Employee> engine = new RulesEngine<Employee>();
public void AddRules(IRule<Employee> rule)
{
engine.AddRules(rule);
//engine.AddRules(new NameLengthRuleForEmployee());
}
public bool validateEntity(Employee employee)
{
List<IRule<Employee>> rulesList = engine.GetRulesList();
//No need for type checking. Overcame Invariance problem
bool status = true;
foreach (IRule<Employee> theRule in rulesList)
{
if (!theRule.IsValid(employee))
{
status = false;
break;
}
}
return status;
}
}
public class RulesEngine<TEntity> where TEntity : IEntity
{
private List<IRule<TEntity>> ruleList = new
List<IRule<TEntity>>();
public void AddRules(IRule<TEntity> rule)
{
//invariance is the key term
ruleList.Add(rule);
}
public List<IRule<TEntity>> GetRulesList()
{
return ruleList;
}
}
The challange is for your rules to know which property of what type to validate. You can either provide this by implementing an interface that provides just that as suggested by SLaks or by quessing it dynamically or by providing a concrete rule class with a bit more information on how to access the given property, e.g.:
class NameRule<T> : IRule<T>
{
private Func<T, string> _nameAccessor;
public NameRule(Func<T, string> nameAccessor)
{
_nameAccessor = nameAccessor;
}
public bool IsValid(T instance)
{
return _nameAccessor(instance).Length > 10;
}
}
this ofcourse can be used in the following way:
NameRule<Employee> employeeNameRule = new NameRule<Employee>(x => x.name);
employeeManager.addRule(employeeNameRule);