C# reuse instance method - c#

I have 3 classes that have instance functions that are completely identical. Is there any way to reuse these instance methods or should I have a copy in all 3 classes e.g.
public class myclass1
{
public string METHOD;
public string RATE;
public string QTY;
void parseFunctionA()
{
}
void parseFunctionB()
{
}
void parseFunctionC()
{
}
}
public class MYCLASS2
{
public string PRICE;
public string WEIGHT;
void parseFunctionA()
{
}
void parseFunctionB()
{
}
void parseFunctionC()
{
}
}

For me two most popular ways would be to do it using:
Inheritance:
public class Program
{
public static void Main(string[] args)
{
var one = new myclass1();
var two = new myclass2();
one.parseFunctionA();
two.parseFunctionC()
}
// Common class can be abstract if you do want to
// prevent it to be instantiated by itself (prevents var common = new Common())
public class Common
{
// Methods made public only for example usage in Main
public void parseFunctionA()
{
}
public void parseFunctionB()
{
}
public void parseFunctionC()
{
}
}
public class myclass1 : Common
{
public string METHOD;
public string RATE;
public string QTY;
}
public class myclass2 : Common
{
public string PRICE;
public string WEIGHT;
}
}
Or composition:
public class Program
{
public static void Main(string[] args)
{
var common = new Common();
var one = new myclass1(common);
var two = new myclass2(common);
}
public class Common
{
public void parseFunctionA()
{
}
public void parseFunctionB()
{
}
public void parseFunctionC()
{
}
}
public class myclass1
{
private Common _common;
public myclass1(Common common)
{
_common = common;
}
public string METHOD;
public string RATE;
public string QTY;
// use _common as you see fit, in methods, in properties, etc.
}
public class myclass2
{
private Common _common;
public myclass2(Common common)
{
_common = common;
}
public string PRICE;
public string WEIGHT;
// use _common as you see fit, in methods, in properties, etc.
}
}
There are also other methods mentioned in comments under your original post.
Mind that there are no safety features in this example.

Related

Dependency injection in nested dynamic object creation?

I have a quite complex application with objects that are nested quite deep from Main and I would like to avoid passing all the dependencies down from the top-level objects and down to the bottom where it might be needed / used.
This is some sample code to illustrate, but is very simplified:
internal class Program
{
public interface IPriceList
{
double GetPrice();
}
public class PriceList : IPriceList
{
public double GetPrice() { return 4.3; }
}
public abstract class Condition
{
public abstract bool IsTrue();
}
public class A
{
private List<Condition> _conditions = new List<Condition>();
public A()
{
}
public void CreateConditionsFromJson()
{
// Read from JSON and dynamically create conditions (not as simple as below)
_conditions.Add(new PriceIsHigherCondition(3.4, ???))
}
}
public class PriceIsHigherCondition : Condition
{
double _price;
IPriceList _priceLIst;
public PriceIsHigherCondition(double price, IPriceList priceList)
{
_price = price;
_priceLIst = priceList;
}
public override bool IsTrue()
{
return _price > _priceLIst.GetPrice();
}
}
static void Main(string[] args)
{
// A is not created here, but deeper down
}
}
It's tempting to create a static class, set the member variables in Main and then access it in the constructors at the bottom level (the condition):
public static class ConditionDependencies
{
public static IPriceList PriceList { get; set; }
}
Any more elegant solution?
I kind of like this (even it might be an anti-pattern):
Define a public static class for dependencies:
public static class ConditionDependencies
{
public static IPriceList PriceList { get; set; }
}
In Main, setup the dependencies:
static void Main(string[] args)
{
// Setup dependencies
ConditionDependencies.PriceList = new PriceList();
}
In a constructor anywhere needing a dependency, just get it:
public class PriceIsHigherCondition : Condition
{
double _price;
IPriceList _priceLIst;
public PriceIsHigherCondition(double price)
{
// Inject Dependencies
_priceLIst = ConditionDependencies.PriceList;
_price = price;
}
public override bool IsTrue()
{
return _price > _priceLIst.GetPrice();
}
}
Is it an anti-pattern? Why? What are the pitfalls?

Lazy decorator - The lazily-initialized type does not have a public, parameterless constructor

I cant make working the code below.. Do I need other class that impolement my IComponent with paratmeterless consturctor?
public class Program
{
public static void Main()
{
var lazy = new Lazy<IComponent>();
IComponent comp = lazy.Value;
var client = new ComponentClient(comp);
client.Run();
}
}
public interface IComponent
{
void Something();
}
public class LazyComponent : IComponent
{
public Lazy<IComponent> _LazyComponent { get; set ;}
public LazyComponent(Lazy<IComponent> lazyComponent)
{
_LazyComponent = lazyComponent;
}
public void Something()
{
_LazyComponent.Value.Something();
}
}
public class ComponentClient
{
public IComponent _Component { get; set; }
public ComponentClient(IComponent component)
{
_Component = component;
}
public void Run()
{
_Component.Something();
}
}
You need to tell the Lazy how to construct the component, by giving it a factory method.
https://learn.microsoft.com/en-us/dotnet/api/system.lazy-1?view=netframework-4.8
public class Program
{
public static void Main()
{
var lazy = new Lazy<IComponent>(() => new RealComponent());
var lazyComponent = new LazyComponent(lazy);
var client = new ComponentClient(lazyComponent);
client.Run();
}
}

Downcasting a List<AbstractClass> object to what the object actually is

I have a ParentClass. Two classes are inherit from it, FirstChildClass and SecondChildClass. A class MultipleValueTypes contains a Dictionary and a method that adds values to it. My intention is to be able to pass values of different classes, which inherit from the same abstract class to the value parameter of the Dictionary. Therefore, I initialize the dictionary with the value List<ParentClass> so that I would be able to add objects made with the child classes to the Dictionary. I can do this, but I cannot access them, therefore in the abstract class I create a way to tell them apart, a virtual method that both the children classes override to return their own class type.
I test the values they return against the enum itself and based on whether the condition is fulfilled, the object would be casted as what it is instead of a List<ParentClass>. Is this the wrong approach? Is this impossible?
I think it should work, because in my thinking the FirstObject and SecondObject are still objects of their respective classes, so casting should work and I should be able to access the overridden method.
What doesn't work: I cannot access the method that returns what type of class it is, because it only gets methods from the List<ParentClass>.
What I've tried so far: searching for a way to access the method, but I did not find any.
What I still need help with: everything mentioned above.
public abstract class ParentClass
{
public string Name { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
}
public class FirstChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public FirstChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the FirstChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public SecondChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the SecondChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public Dictionary<string, List<ParentClass>> ADictionary = new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if (!ADictionary.ContainsKey(Name))
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
class Program
{
static void Main(string[] args)
{
FirstChildClass FirstObject = new FirstChildClass("FirstObject");
SecondChildClass SecondObject = new SecondChildClass("SecondObject");
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if(TestDictionary.ADictionary["FirstObject"].TypeOfClass() == ParentClass.ChildClasses.FirstChildClass) ///List<ParentClass>' does not contain a definition for 'TypeOfClass' and no accessible extension method 'TypeOfClass' accepting a first argument of type 'List<ParentClass>' could be found (are you missing a using directive or an assembly reference?)
{
TestDictionary.ADictionary["FirstObject"] = (FirstChildClass)TestDictionary.ADictionary["FirstObject"]; ///Cannot convert type 'System.Collections.Generic.List<Dictionary.ParentClass>' to 'Dictionary.FirstChildClass
}
}
}
You forgot to use indexer of the list value of the key of the dictionary here:
==> TestDictionary.ADictionary["FirstObject"][0]
Here is your code now refactored too:
class Program
{
static void Main(string[] args)
{
var FirstObject = new FirstChildClass("FirstObject");
var SecondObject = new SecondChildClass("SecondObject");
FirstObject.ReturnMessage();
SecondObject.ReturnMessage();
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if ( TestDictionary.ADictionary["FirstObject"][0].TypeOfClass()
== ParentClass.ChildClasses.FirstChildClass )
{
TestDictionary.ADictionary["FirstObject"][0]
= (FirstChildClass)TestDictionary.ADictionary["FirstObject"][0];
}
Console.ReadKey();
}
}
public abstract class ParentClass
{
public string Name { get; set; }
public string RandomValue { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public virtual void ReturnMessage()
{
Console.WriteLine($"This is the {this.GetType().Name} instance");
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
}
public class FirstChildClass : ParentClass
{
public FirstChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
public SecondChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public readonly Dictionary<string, List<ParentClass>> ADictionary
= new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if ( !ADictionary.ContainsKey(Name) )
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
If the intention is to cast the whole list from List<ParentClass> to List<FirstChildClass> and List<SecondChildClass>, then Linq is your friend, just use the Cast function:
List<FirstChildClass> firstChildClasses = TestDictionary.ADictionary["FirstObject"]
.Cast<FirstChildClass>().ToList();
List<SecondChildClass> secondChildClasses = TestDictionary.ADictionary["SecondObject"]
.Cast<SecondChildClass>().ToList();

C# instantiate class with varying "child" class

I have a class that has some derived classes. That works.
I want to instantiate the "parent" class. Got that far...
But I want to instantiate it with one of the "child" classes, and then possibly change that "child" class later. Maybe the deriving is inappropriate here.
Take the following example:
public class Unicorn {
public string Horn { get; set; }
public Unicorn(){
}
}
public class BadUnicorn : Unicorn{
public string Rainbow()
{
return "dark rainbow";
}
}
public class GoodUnicorn : Unicorn{
public string Rainbow()
{
return "light rainbow";
}
}
I could instantiate one of the children, but then if I change one from "good" to "bad", I would have to re-instantiate. And maybe that's just the way it is, and that would be an acceptable answer if that's all there is to it.
I rather want to instantiate a Unicorn, and then be able to change it from Good to Bad to maintain information stored on that Unicorn, but have access to the current methods and properties of the "child" class.
That way when I call Unicorn.Rainbow() it calls the desired method of the "child" class.
I'm a little new to C#, is there a pattern that fits this bill?
You can't do what you want with polymorphism. You cannot change an instance of class from one to another. Once it is created it is always the same type.
You can use composition though.
Here's what you'd need to do:
public class Unicorn
{
public string Horn { get; set; }
public Unicorn(Rainbow rainbow)
{
_rainbow = rainbow;
}
public void SetRainbow(Rainbow rainbow)
{
_rainbow = rainbow;
}
private Rainbow _rainbow;
public string Rainbow()
{
return _rainbow.Colour();
}
}
public abstract class Rainbow
{
public abstract string Colour();
}
public class BadRainbow : Rainbow
{
public override string Colour()
{
return "dark rainbow";
}
}
public class GoodRainbow : Rainbow
{
public override string Colour()
{
return "light rainbow";
}
}
You can test like this:
var unicorn = new Unicorn(new GoodRainbow());
Console.WriteLine(unicorn.Rainbow());
unicorn.SetRainbow(new BadRainbow());
Console.WriteLine(unicorn.Rainbow());
This outputs:
light rainbow
dark rainbow
The instance of Unicorn stays the same, but you can change the rainbow.
Here's my take on delegate dictionary. While it seems superfluous to use Func instead of just string, if the method have additional functionality like calculation or need parameters, you're covered with Func.
public class Unicorn
{
static Dictionary<Attitude, Func<string>> RainbowByAttitude =
new Dictionary<Attitude, Func<string>>()
{
[Attitude.Bad] = new Func<string>(() => "dark rainbow"),
[Attitude.Good] = new Func<string>(()=>"light rainbow")
};
public string Horn { get; set; }
public enum Attitude
{
Good,Bad
}
public Attitude attitude;
public Unicorn(Attitude attitude)
{
this.attitude = attitude;
}
public string Rainbow() => RainbowByAttitude[attitude].Invoke();
}
class Program
{
static void Main(string[] args)
{
Unicorn unicorn;
unicorn = new Unicorn(Unicorn.Attitude.Bad);
Console.WriteLine(unicorn.Rainbow());
unicorn.attitude = Unicorn.Attitude.Good;
Console.WriteLine(unicorn.Rainbow());
}
}
It seems like a state pattern to me like this:
public abstract class UnicornState
{
public abstract UnicornState Change();
public abstract string Rainbow();
}
public sealed class GoodUnicornState : UnicornState
{
public override UnicornState Change()
{
return new BadUnicornState();
}
public override string Rainbow()
{
return "light rainbow";
}
}
public sealed class BadUnicornState : UnicornState
{
public override UnicornState Change()
{
return new GoodUnicornState();
}
public override string Rainbow()
{
return "dark rainbow";
}
}
public class Unicorn
{
public string Horn { get; set; }
public UnicornState State { get; set; }
public string Rainbow => State.Rainbow();
}
Usage:
var u = new Unicorn();
u.State = new GoodUnicornState();
Console.WriteLine(u.Rainbow);
u.State = u.State.Change();
Console.WriteLine(u.Rainbow);

Interfaces and inheritance with derived class

I am stuck on interfaces and inheritance. If I implement two classes who both have an interface each, how would I be able to add the properties of Class A and B together? For instance I wanted to associate firstitem with the seconditem.
public interface IAlpha
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/AddBravoToAlpha/{firstitem}/{seconditem}")]
void AddBravoToAlpha(int firstitem, int seconditem);
}
public interface IBravo
{
// what goes in here?
}
public Class Alpha
{
public Alpha()
{
AlphaAdd = new List<Bravo>();
}
int Firstitem { get; set }
public List<Bravo> AlphaAdd { get; set; }
}
public Class Bravo
{
public Bravo()
{
BravoAdd = new List<Alpha>(); //not sure if Bravo can access Alpha (derived class)
}
int Seconditem { get; set }
Guid Indexer { get; set }
public List<Alpha> BravoAdd { get; set; }
}
public Class BravoDoesAlpha : IBravo, IAlpha //????
{
List<Alpha> alpha = new List<Alpha>();
List<Bravo> bravo = new List<Bravo>();
public void AddBravoToAlpha(int firstitem, int seconditem)
{
var result = alpha.Where(n => String.Equals(n.Firstitem, firstitem)).FirstOrDefault();
var result1 = bravo.Where(n => String.Equals(n.Seconditem, seconditem)).FirstOrDefault();
if (result != null)
{
result.BravoAdd.Add(new Alpha() { Firstitem = firstitem });
}
if (result1 != null)
{
result1.AlphaAdd.Add(new Bravo() { Seconditem = seconditem });
}
}
}
Okay, so the question you are being asked is basically one about how to do a certain kind of refactoring known as "extracting" an interface.
This is one of the more easy refactorings to do and to understand if you understand interfaces vs. types.
All interfaces are types, but not all types are interfaces.
Now let's assume we are dealing in a world with two families of types: classes and interfaces (as in your example).
Instead of working your example directly, I will work a different but clearer example that does not use Alpha, Bravo, Charlie, Epsilon, etc. because this kind of stuff makes it harder to see the meaning.
First, here's the before:
public class Dog
{
public void Bark() { Console.WriteLine("Woof!"); }
public int NumberOfDogLegs { get { return 2; } }
public int NumberOfDogFriends { get; set; } // this can be set
private string SecretsOfDog { get; set; } // this is private
}
public class DoorBell
{
public void Chime() { Console.WriteLine("Ding!"); }
}
To extract the interface of a class, simply, well, extract all the public members of the class to an interface.
public interface IDog
{
void Bark();
int NumberOfDogLegs { get; }
int NumberOfDogFriends { get; set; }
}
public interface IDoorBell
{
void Chime();
}
Now to really make use of OOP, you can find a way to abstract IDog and IDoorBell. What do they have in common? Well, the obvious one is they both make a noise. So we make a new interface, public interface IMakeANoise and say that IDog and IDoorBell both implement it.
public interface IMakeANoise
{
void MakeNoise();
}
public interface IDog : IMakeANoise
{
void Bark();
int NumberOfDogLegs { get; }
int NumberOfDogFriends { get; set; }
}
public interface IDoorBell : IMakeANoise
{
void Chime();
}
And now we have a new method to implement on Dog and DoorBell.
public class Dog : IDog
{
public void Bark() { Console.WriteLine("Woof!"); }
public int NumberOfDogLegs { get { return 2; } }
public int NumberOfDogFriends { get; set; } // this can be set
private string SecretsOfDog { get; set; } // this is private
public void IMakeANoise() { Bark(); }
}
public class DoorBell : IDoorBell
{
public void Chime() { Console.WriteLine("Ding!"); }
public void IMakeANoise() { Chime(); }
}
Now let's say we are actually writing a video game and Dog and DoorBell are both things that we can show on the screen. Well, this makes them a lot bigger because we will need to provide more information like their coordinates, their states, etc.
In this case, Dog and DoorBell may be very different to us but are similar enough to potentially merit sharing a base class. (Really, this is a stretch, but it does get the point across.)
Without adding all those new interfaces and their implementations, let's just do the "sharing a base class" refactoring for what we already have.
public class RenderableThing : IMakeANoise, IDoAThousandOtherThings
{
protected virtual string MyNoiseToMake { get { return ""; } }
public virtual void MakeANoise()
{
Console.WriteLine(MyNoiseToMake);
}
}
public class Dog : RenderableThing, IDog
{
protected override string MyNoiseToMake { get { return "Woof!"; } }
public void Bark() { MakeANoise(); } // see what we did there?
// Notice that I am not declaring the method MakeANoise because it is inherited and I am using it by overriding MyNoiseToMake
public int NumberOfDogLegs { get { return 2; } }
public int NumberOfDogFriends { get; set; } // this can be set
private string SecretsOfDog { get; set; } // this is private
}
public class DoorBell : RenderableThing, IDoorBell
{
public void Chime() { Console.WriteLine("Ding!"); }
public override void MakeANoise()
{
Chime(); Chime(); Chime(); //I'll do it my own way!
}
}
You may wonder, what's the point? So we can do this...
IMakeANoise dogNoiseMaker = new Dog();
IMakeANoise doorBellNoiseMaker = new DoorBell();
IList<IMakeANoise> listOfNoiseMakers = new List<IMakeANoise>();
listOfNoiseMakers.Add(dogNoiseMaker);
listOfNoiseMakers.Add(doorBellNoiseMaker);
foreach (IMakeANoise noiseMaker in listOfNoiseMakers)
{
noiseMaker.MakeANoise();
}
// This will output
// Woof!
// Ding!
// Ding!
// Ding!
I'm going to take a shot in the dark and venture a guess that you don't quite understand what interfaces and inheritance is. I'll start off by explaining what interfaces are:
Interfaces contain only the definitions of methods, properties, events or indexers that an inheriting class must implement.
For example:
interface IExample
{
void HelloWorld();
}
class ExampleClass : IExample
{
public void HelloWorld()
{
Console.WriteLine("Hello world.");
}
}
Now for Inheritance; when you derive a class from a base class the derived class will inherit all members of the base class except for the constructors. Note: Depending on the accessibility of the members in the base class it's children may or may not be able to access the parents members.
public class Animal
{
public string Name { get; set; }
public Animal(string name)
{
Name = name;
}
public void Talk()
{
Console.WriteLine("{0} is talking", Name);
}
}
public class Cat : Animal
{
public Cat(string name) : base(name) { }
}
public class Dog : Animal
{
public string FurColor { get; set; }
public Dog(string name, string furColor) : base(name)
{
FurColor = furColor;
}
public void Greeting()
{
Console.WriteLine("{0} has {1} fur.", Name, FurColor);
}
}
class Program
{
static void Main(string[] args)
{
var cat = new Cat("Rex");
cat.Talk();
var dog = new Dog("Beanie", "Red");
dog.Talk();
}
}

Categories