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;
Related
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());
}
}
I am trying to refactor some code and have to admit that I am new to the concept of generics.
I have a base class:
BaseVarDef.cs:
using UnityEngine;
public abstract class BaseVarDef<T> : ScriptableObject
{
[Multiline]
public string DeveloperDescription = "";
public T Value;
public void SetValue(T value)
{
Value = value;
}
}
Then I have several classes that derive from this. But they all contain the same 3 methods that I would like to refactor into this generic base class. The only difference is they expect either the generic type or class that is currently defining them.
FloatVar.cs
using UnityEngine;
[CreateAssetMenu(fileName = "New FloatVar", menuName = "Variables/FloatVar")]
public class FloatVar : BaseVarDef<float>
{
public void SetValue(FloatVar value)
{
Value = value.Value;
}
public void ApplyChange(float amount)
{
Value += amount;
}
public void ApplyChange(FloatVar amount)
{
Value += amount.Value;
}
}
StringVar.cs
using UnityEngine;
[CreateAssetMenu(fileName = "New StringVar", menuName = "Variables/StringVar")]
public class StringVar : BaseVarDef<string>
{
public void SetValue(StringVar value)
{
Value = value.Value;
}
public void ApplyChange(string amount)
{
Value += amount;
}
public void ApplyChange(StringVar amount)
{
Value += amount.Value;
}
}
Is there a way to refactor the: SetValue and the 2 overloaded ApplyChange methods into BaseVarDef.cs?
Thanks in advance
I think you can define all Apply and Set in Base class
public abstract class BaseVarDef<T>
{
public string DeveloperDescription = "";
public T Value;
public void SetValue(T value)
{
Value = value;
}
public void SetValue(BaseVarDef<T> value)
{
Value = value.Value;
}
public void ApplyChange(T amount)
{
AddValue(amount);
}
public void ApplyChange(BaseVarDef<T> amount)
{
AddValue(amount.Value);
}
protected abstract void AddValue(T val);
}
public class FloatVar : BaseVarDef<float>
{
protected override void AddValue(float val)
{
Value += val;
}
}
If you can just add those methods to the original base class (and then remove the abstract from it), and then you just do BaseVarDef<string> or BaseVarDef<float>. No more need for the FloatVar or StringVar classes!
The tricky part here is the += operator, which can't be applied to generics (at least there is no constraint I'm aware of that allows you to specify the type implements an operator).
So you could either make an abstract Add method that derived classes must implement as Svetlana describes, or you can use dynamic as shown below (and get rid of the need for derived classes altogether).
The one problem with dynamic is that there is no compile time checking with dynamic types, so it's not foolproof. The type T must overload the + operator or you'll get a runtime exception. You could avoid that by wrapping the line Value = amt + val; in a try/catch, but then you may get unexpected behavior.
public class BaseVarDef<T>
{
public string DeveloperDescription { get; set; } = "";
public T Value { get; private set; }
public void SetValue(T value)
{
Value = value;
}
public void SetValue(BaseVarDef<T> value)
{
Value = value.Value;
}
public void ApplyChange(T amount)
{
AddToValue(amount);
}
public void ApplyChange(BaseVarDef<T> amount)
{
AddToValue(amount.Value);
}
private void AddToValue(T amount)
{
dynamic amt = amount;
dynamic val = Value;
// Empty catch to avoid runtime exception if 'T' doesn't support the '+' operator
try { Value = amt + val; }
catch { }
}
}
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
I have something like this:
public class Ship
{
public void PositionX_pixels_set1(float _position_x){position_x = _position_x;}
public class Engine : Ship
{
public int engines() { return 5; }
public class Piston
{
public int pistons(){return 5;}
}
}
}
void Main
{
Ship ship = new Ship()
int a = ship.Engine.Piston.pistons;//why this not working?
}
I don't know what I'm doing wrong. Why isn't "ship.Engine.Piston.pistons" working?
Because Engine is type inside the Ship class, and its member.
To fix this can do something like:
public class Ship
{
public void PositionX_pixels_set1(float _position_x){position_x = _position_x;}
private void Engine _myEngine = new Engine(); //DEFINE ENGINE MEMBER
public Engine MyEngine { //DEFINE A PROPERTY TO ACCESS THAT MEMBER
get {
return _myEngine;
}
}
public class Engine : Ship
{
public int engines() { return 5; }
private Piston _myPiston = new Piston();//DEFINE PISTON MEMBER
public Piston MyPiston {//DEFINE A PROPERTY TO ACCESS THAT
get {
return _myPiston ;
}
}
public class Piston
{
public int pistons(){return 5;}
}
MEMBER
}
}
and after use it like:
int a = ship.MyEngine.MyPiston.pistons
You must initiate an object of your sub type (Nested type) in order to access its method, in your case you are not creating any object of your nested types so you can not access its methode.
While you create a new Ship() you are not creating any Engine or Piston, so you can not access the methode Pistons() of the non existing object.