C#: How to refer to child class's member in parent method - c#

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;
}
}

Related

Code Refactoring to remove the duplicate code

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());
}
}

C# Parenting from Generic type of Generic type class? Too complex for me to form more fitting question to the problem :|

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!

Hiding static variables/functions and using them in base class

I have a base class with a protected-level static variable, a protected-level static function, and a public function:
public class ClassA
{
protected static int Size = 4;
public static byte[] DoSomething(byte[] params)
{
// use Size somehow
params = DoSomethingElse(params);
return params;
}
protected static byte[] DoSomethingElse(byte[] params)
{
// do whatever
return params;
}
}
And a derived class that hides the protected-level variable and function:
public class ClassB : ClassA
{
public new static int Size = 2;
protected new static byte[] DoSomethingElse(byte[] params)
{
// do something different than base class
return params;
}
}
Now, when I call ClassB.DoSomething, I want the Size value and DoSomethingElse from the ClassBto be used, but the ClassA values are used instead. Is there a way to make this use the ClassB variable and method?

C# Mock a Class With an Internal Property Setter

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

How can I ensure that certain method and fields are visible only to a child class?

I'm not sure if this is possible but I want to be able to have fields/method of a base class to be visible to the parent.
Say for example I have a class:
public class ExampleFile
{
private Stream _stream;
private long _baseoffset;
public ExampleFile(Stream input)
{
_stream = input;
_baseoffset = input.Position;
}
public void SeekTo(long offset)
{
_stream.Seek(offset + _baseoffset, SeekOrigin.Begin);
}
}
And I then use that class as a base for another class:
public class ExampleClass : ExampleFile
{
public ExampleClass(Stream input)
: base(input)
{
}
public byte[] GetSomething()
{
byte[] id = new byte[5];
SeekTo(2);
base._stream.Read(id, 0, 5);
return id;
}
}
Is there any way I can make the fields/methods of ExampleFile only visible to ExampleClass?
Use the protected modifier instead of public/private on the fields/properties/methods you want exposed to child classes.
public class ExampleFile
{
protected Stream _stream; // no longer private, so the inherited
protected long _baseoffset; //classes can access them
public ExampleFile(Stream input)
{
_stream = input;
_baseoffset = input.Position;
}
public void SeekTo(long offset)
{
_stream.Seek(offset + _baseoffset, SeekOrigin.Begin);
}
}
What do you mean by base class? The base class is supposed be the parent in your case! If you want a member of a class to be accessible to one of its descendants, use the protected modifier. If you want a member of the child class to be accessible to its parent, do so through a getter.

Categories

Resources