I have three methods in two classes in which two methods have the same code but with different inheritance. How can I reduce the duplicate codes by adding a new class? I have tried to simplify it with a simple sample. Hope the code makes sense. How can I refactor this? Any help on this much appreciated.
GetConnection.cs
public class GetConnection1 : LookupConnection1
{
public override int GetConnectionCount()
{
/* This method is same as that of the GetConnection2 class file but inherits from other
class named LookUpConnection1
Need to refactor this duplicate method */
int conCount = base.GetConnectionCount();
int value = GetAvailableConnections(conCount);
return value;
}
private int GetAvailableConnections(int conCount)
{
/* This method is same as that in GetConnection2. This method is
exact replica that is in GetConnection2 class
Need to refactor this duplicate method */
int value = 0;
for (int i = 0; i < conCount; i++)
value = GetConnection(value);
return value;
}
private int GetConnection(int value)
{
/* This is the method which differs from the GetConnection2 class. */
return value + 10;
}
}
GetConnection2 class:
public class GetConnection2 : LookUpConnection2
{
public override int GetConnectionCount()
{
/* This method is same as that of the GetConnection1 class file but inherits from other
class named LookUpConnection2
Need to refactor this method*/
int conCount = base.GetConnectionCount();
int value = GetAvailableConnections(conCount);
return value;
}
private int GetAvailableConnections(int conCount)
{
/* This method is same as that in GetConnection1. This method is
exact replica that is in GetConnection1 class
Need to refactor this duplicate method */
int value = 0;
for (int i = 0; i < conCount; i++)
value = GetConnection(value);
return value;
}
private int GetConnection(int value)
{
/* This is the method which differs from the GetConnection2 class. */
return value + 30;
}
}
LookupConnection1 class file
public class LookupConnection1 : BaseConnection
{
public override int GetConnectionCount()
{
return 20;
}
}
LookUpConnection2 class file
public class LookUpConnection2 : BaseConnection
{
public override int GetConnectionCount()
{
return 10;
}
}
BaseConnection class file
public abstract class BaseConnection
{
public abstract int GetConnectionCount();
}
public class Program
{
static void Main()
{
GetConnection1 connection1 = new GetConnection1();
GetConnection2 connection2 = new GetConnection2();
Console.Write(connection1.GetConnectionCount());
Console.Write(connection2.GetConnectionCount());
}
}
Thanks in Advance,
You have to create an unique LookupConnection class and move GetAvailableConnections and GetConnection methods to the LookupConnection class. Below is the refactored code, hope it helps you!!!
// Create a unique LookupConnection class
public class LookupConnection : BaseConnection
{
// Private field to hold the initial value
private readonly int _count;
// Pass the expected value through the constructor.
// That will allow you to pass values as needed in each LookupConnection inheritance.
public LookupConnection(int count)
{
_count = count;
}
// Override GetConnectionCount method to use
// the GetAvailableConnections defined in this class
public override int GetConnectionCount()
{
return GetAvailableConnections(_count);
}
// If you put GetAvailableConnections in the LookupConnection class
// you don't need to worry about what it does, because always it does the same.
// Make it virtual if later you want change its behavior.
protected virtual int GetAvailableConnections(int conCount)
{
int value = 0;
for (int i = 0; i < conCount; i++)
value = GetConnection(value);
return value;
}
// Add the GetConnection to the LookupConnection and make it
// virtual in order to override in the different GetConnection classes
protected virtual int GetConnection(int value)
{
return value;
}
}
// This is how your class will look like
public class GetConnection1 : LookupConnection
{
// Pass the value to the base constructor as needed
public GetConnection1 () : base(20)
{
}
// Here you can override the GetConnection and add the particular behavior for this class
protected override int GetConnection(int value)
{
return value + 10;
}
}
// This is how your class will look like
public class GetConnection2 : LookUpConnection
{
// Pass the value to the base constructor as needed
public GetConnection2 () : base(10)
{
}
// Here you can override the GetConnection and add the particular behavior for this class
protected override int GetConnection(int value)
{
return value + 30;
}
}
public class Program
{
static void Main()
{
GetConnection1 connection1 = new GetConnection1();
GetConnection2 connection2 = new GetConnection2();
Console.Write(connection1.GetConnectionCount());
Console.Write(connection2.GetConnectionCount());
}
}
Related
I am implementing 2 kinds of ByteMessage creater class using Inheritance like below.
abstract class MessageCreater
{
int messageSize;
void validateMessage(byte[] message)
{
if (message.Length!=messageSize)
throw new Exception("Length not proper");
}
}
class XMessageCreater: MessageCreater
{
static readonly int messageSize = 10;
public byte[] Create()
{
byte[] message;
// specific procedure here
validateMessage(message);
return message;
}
}
class YMessageCreater: MessageCreater
{
static readonly int messageSize = 20;
public byte[] Create()
{
// specific procedure here
validateMessage(message);
return message;
}
}
My problem is, to make it short, When validating the message length, messageSize always equals 0 (this is perhaps because the parent class member "messageSize" was being initialized as 0).
when validating in XMessageClass, messageSize variable should be 10, and in YMessageClass, should be 20.
Can you give me a clue to make it work like this?
Using Inheritance is not necessary.
The problem is that the fields are completely different for each class, despite the same name. It sounds like you want a virtual property that you can override instead:
abstract class MessageCreator
{
protected abstract int messageSize {get;}
void validateMessage(byte[] message)
{
if (message.Length != messageSize)
throw new Exception("Length not proper");
}
}
class XMessageCreator: MessageCreator
{
override int messageSize {get;} = 10;
public byte[] Create()
{
byte[] message;
// specific procedure here
validateMessage(message);
return message;
}
}
class YMessageCreator: MessageCreator
{
override int messageSize {get;} = 20;
public byte[] Create()
{
// specific procedure here
validateMessage(message);
return message;
}
}
I have trouble with figuring out how can I use generic types to solve my problem.
Also I don't know how to describe my problem in short so I will make simplified version of my problem as extended exmplanation.
I am making system for switching quality, transitioning quality levels between different types of 'component' class.
I have base class like:
public abstract class QualityLevel_Base
{
public bool Enabled = true;
public virtual void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
if (value >= 1) Enabled = b.Enabled; else if (value <= 0) Enabled = a.Enabled;
}
protected static double Lerp(double a, double b, double t) { return (1 - t) * a + t * b; }
}
Then I inherit from it like:
public sealed class QualityLevel_LightSource : QualityLevel_Base
{
public double Intensity;
public double Range;
public int ShadowsQuality;
public override void Transition(QualityLevel_Base a, QualityLevel_Base b, double value)
{
QualityLevel_LightSource la = a as QualityLevel_LightSource; // One part of my problem - avoid casting
QualityLevel_LightSource lb = b as QualityLevel_LightSource;
base.Transition(a, b, value);
Intensity = Lerp(la.Intensity, lb.Intensity, value);
/* etc... */
}
}
Then I want to manage quality levels in other class and be able to apply settings onto desired component class.
So I have base class to manage any count of quality levels:
public abstract class QualityManager_Base
{
public Component SourceComponent { get; protected set; }
public List<QualityLevel_Base> QualityLevels { get; protected set; }
public virtual void Initialize(Component component, int qualityLevelsCount)
{
QualityLevels = new List<QualityLevel_Base>();
SourceComponent = component;
AutoQualitySettings(qualityLevelsCount);
}
public virtual void AutoQualitySettings(int qualityLevelsCount) { }
public virtual void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
SourceComponent.Enabled = qualityLevel.Enabled;
}
}
And I inheriting it for LightSource like:
public sealed class QualityManager_LightSource : QualityManager_Base
{
public LightSource Light { get; private set; }
public override void Initialize(Component component, int qualityLevelsCount)
{
LightSource light = component as LightSource; // Another situation when I would like to avoid casting
Light = light;
base.Initialize(light, qualityLevelsCount);
}
public override void AutoQualitySettings(int qualityLevelsCount)
{
for (int i = 0; i < qualityLevelsCount; i++)
{
QualityLevel_LightSource lightSettings = new QualityLevel_LightSource();
lightSettings.Intensity = Light.Intensity;
lightSettings.Range = Light.Range;
lightSettings.ShadowsQuality = i / qualityLevelsCount;
if (i == qualityLevelsCount - 1) lightSettings.Enabled = false;
}
}
public override void ApplyQualitySettings(QualityLevel_Base qualityLevel)
{
base.ApplyQualitySettings(qualityLevel);
// To my Question: I want to use generic type to avoid casting
QualityLevel_LightSource lightSettings = qualityLevel as QualityLevel_LightSource;
Light.Intensity = lightSettings.Intensity;
Light.Range = lightSettings.Range;
Light.ShadowsQuality = lightSettings.ShadowsQuality;
}
}
Actually I managed to use generic types on this problem making stuff like:
public abstract class QualityLevel_Base<T> where T : QualityLevel_Base<T> { /*...*/ }
public class QualityLevel_LightSource : QualityLevel_Base<QualityLevel_LightSource> { /*...*/ }
public abstract class QualityManager_Base
{
public List<QualityLevel_Base> QualityLevels; // Would like to define it like that but I have to do it
// like that:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
}
Then doing something like this causes error:
public abstract class QualityManager_Base<T> where T : QualityLevel_Base<T>
{
public List<QualityLevel_Base<T>> QualityLevels;
public virtual void AddComponentForQualityManager(Component comp)
{
if (QualityLevels == null) QualityLevels = new List<QualityLevel_Base<T>>();
LightSource light = comp as LightSource;
if (light != null)
{
QualityManager_LightSource lightManager = new QualityManager_LightSource();
QualityLevels.Add(lightManager); // Then I Can't do this because: "cannot convert from 'QualityManager_LightSource' to 'QualityLevel_Base<T>' "
}
/* ... */
}
}
"cannot convert from 'QualityManager_LightSource' to 'QualityLevel_Base'"
There is of course more going on in my system, it is just very simplified version to define my question: How can I avoid casting classes, how can I do it correctly?
Thanks!
I have to override a function in a base class in such a way that calls to inherited functions also lead to calls to this overridden function instead of the base implementation.
class base_class
{
string abc;
public int get_1()
{
return 1;
}
public int get_number()
{
return get_1()+1;
}
}
class der_class : base_class
{
public int get_1()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
der_class abc = new der_class();
Console.WriteLine(abc.get_number());
Console.ReadKey();
}
}
This prints 2. How can I get the output to be 3 by making the get_number to call overridden get_1?
You need the override keyword to actually override a method, otherwise you are hiding it.
class der_class : base_class
{
// note the word override here!
public override int get_1()
{
return 2;
}
}
Also, you need to make the method virtual in the base class:
class base_class
{
string abc;
// note the word virtual here!
public virtual int get_1()
{
return 1;
}
public int get_number()
{
return get_1()+1;
}
}
I am trying to build a unit test.
The class Position is implemented in a third party library. But for my unit test I need the Size property to be set to a specific value.
public class Position
{
private double _size;
private double Size
{
get
{
return _size;
}
internal set
{
_size = value;
}
}
}
I read this post: How do you create a unit-testing stub for an interface containing a read-only member?
but could not figure out how to make it work for me.
This is the class under test (just a simplified example). The posargument in the CalcPositionMetric() method must be of type Position:
public class PositionMetrics
{
public PositionMetrics()
{}
public double CalcPositionMetric(Position pos)
{
return 2 * pos.Size;
}
}
Here is a piece of my unit test:
using NUnit.Framework;
using NMock;
[TestFixture]
public class PositionUnitTests
{
[Test]
public void TestPosition()
{
Mock<Position> tmpPosMock = mFactory.CreateMock<Position>();
tmpPosMock.Expects.One.GetProperty(v => v.Size).WillReturn(7); /* !!! Exception !!! System.ArgumentException : mock object position has a getter for property Size, but it is not virtual or abstract */
/* Execute Test with tmpPositions*/
PositionMetrics pm = new PositionMetrics();
double result = pm.CalcPositionMetric(tmpPosMock.MockObject)
Assert.AreEqual(14, result);
}
}
But as you can see I get an exception. Could somebody help me to resolve this problem? Any other solutions are also welcome!
Cheers
Konstantin
New answer for the updated question I suggest you to introduce some kind of a proxy interface for that. See the code below:
interface IPosition {
int Size { get; }
}
class Position { //in 3rd party lib
public int Size {
get { return 5; }
}
}
class RealPosition : IPosition { //use this as your real object instead of using Position directly
private Position position;
public RealPosition(Position position) {
this.position = position;
}
public int Size {
get { return position.Size; }
}
}
class MockPosition : IPosition { //use this for testing
public int Size{ get; set; }
}
public class Program {
static void Main(string[] args) {
var pos = new MockPosition { Size = 7 };
Console.WriteLine(Calc(pos)); //prints 14
Console.ReadLine();
}
static int Calc(IPosition pos) { //change your method signature to work with interface
return pos.Size * 2;
}
}
Old answer If the class is not sealed you don't need any mocking libraries. Just use the new modifier for the required properties like this:
class Position {
public int Size { get { return 5; } }
}
class MockPosition : Position {
public new int Size { get; set; }
}
....
var mock= new MockPosition();
mock.Size = 7;
To use these items in some sort of list you'll have to cast them like this:
var items = new List<Position>();
for (int i = 0; i < 5; i++) {
items.Add(new MockPosition { Size = i });
}
foreach (var item in items.Cast<MockPosition>()) {
Console.Write("{0}\t", item.Size); //prints 0 1 2 3 4
}
If it is sealed and the property is not virtual than you'll have to use some other techniques, Moq (which I guess you are using) does not allow that
For example, I have a static class that contain all default methods. What if I want to generate a properties and simultaneously generate a default static method---
static class Default
{
//Auto-Generated
static int DEFAULT_foo1()
{
//Do something
}
static float DEFAULT_var2
{
//Do something
}
}
class Other
{
//Code-Snippet
int var1
{
get
{
return Default.DEFAULT_var1();
}
}
float var2
{
get
{
return Default.DEFAULT_var2();
}
}
}
I think standard inheritance be a good solution.
class OtherBase
{
//Code-Snippet
int var1
{
get
{
return Default.DEFAULT_var1();
}
}
float var2
{
get
{
return Default.DEFAULT_var2();
}
}
}
Derived class:
class Other : OtherBase
{
}
Change the class Default to be a singleton instead of being static. Now you can implement the method as well as the property in the same class with a code snippet. Other classes can derive from Default and inherit the properties automatically.
class Default
{
public static readonly Default Instance = new Default();
protected Default ()
{
}
public static int DoFoo1()
{
//Do something
}
public int Foo1 { get { return DoFoo1(); } }
public static float DoVar2
{
//Do something
}
public float Var2 { get { return DoVar2(); } }
}
class Other : Default
{
// Inherits Foo1 and Var2 automatically
}
Use of Default and Other
int x = Default.DoFoo1();
int y = Default.Instance.Foo1;
Other other = new Other();
int z = other.Foo1;