So here's a simple example put up where I can add and subtract based on a string input. Then instead of calculating on the spot I wanted to create functions so that I can create an interface. The idea: Use the to refer to anything. I want to put and objects in there, with a uniform way of calling the objects (e.g. they all have an interface that exposes a Compute() method) So here are my two pieces of code that I can't get to mesh to complete this.
public class Calculator
{
private Dictionary<string, Func<float,float,float>> _map = new Dictionary<string, Func<float,float,float>>
{
{ "add", (a,b) => a+b },
{ "subtract", (a,b) => a-b },
{ "multiply", (a,b) => a*b },
{ "divide", (a,b) => a/b },
};
public float Compute(float[] numbers, string opCode)
{
var operation = _map[opCode];
float accumulator = numbers[0];
foreach (var n in numbers.Skip(1))
{
accumulator = operation(accumulator, n);
}
return accumulator;
}
}
public class Program
{
public static void Main()
{
var c = new Calculator();
Console.WriteLine(c.Compute( new float[] { 2,2 }, "add"));
Console.WriteLine(c.Compute( new float[] { 3,3 }, "multiply"));
Console.WriteLine(c.Compute( new float[] {-2,2 }, "subtract"));
Console.WriteLine(c.Compute( new float[] { 9,3 }, "divide"));
}
}
that demonstrates what outputs I'm looking for. Now creating the interface how do I use it in a similar fashion to the above framework?
public interface ICalculate
{
int Calculate(int x, int y);
}
public class Add : ICalculate
{
#region ICalculate Members
public int Calculate(int x, int y)
{
return x + y;
}
#endregion
}
public class Subtract : ICalculate
{
#region ICalculate Members
public int Calculate(int x, int y)
{
return x - y;
}
#endregion
}
Related
This question already has answers here:
Changing the value of an element in a list of structs
(7 answers)
Closed 10 months ago.
In the following program, I am unable to modify individual list items:
public class Program
{
static void Main(string[] args)
{
List<Point2d> list = new List<Point2d>();
list.Add(new Point2d(0, 0));
list.Add(new Point2d(0, 1));
foreach (Point2d item in list)
{
item.Print();
}
Point2d p = list[0];
p.Set(-1, -1);
foreach (Point2d item in list)
{
item.Print();
}
Console.ReadKey();
}
}
Output:
(0,0) (0,1) (0,0) (0,1)
My expected output was:
(0,0) (0,1) (-1,-1) (0,1)
What am I doing incorrectly?
Relevant source code:
public struct Point2d : IEquatable<Point2d>
{
public double X { get; set; }
public double Y { get; set; }
#region constructor
public Point2d(double x, double y)
{
X = x;
Y = y;
}
#endregion
public void Print()
{
Console.Write("(");
Console.Write(X);
Console.Write(",");
Console.Write(Y);
Console.Write(") ");
}
public void Set(double x, double y)
{
X = x;
Y = y;
}
public double GetDistance(Point2d otherPoint)
{
return Math.Sqrt(GetSquaredDistance(otherPoint));
}
public double GetSquaredDistance(Point2d otherPoint)
{
return ((otherPoint.X - X) * (otherPoint.X - X))
+ ((otherPoint.Y - Y) * (otherPoint.Y - Y));
}
public Point2d GetTranslated(Point2d center)
{
return new Point2d(X + center.X, Y + center.Y);
}
#region override string ToString()
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("(" + X + " , " + Y + ")");
return sb.ToString();
}
#endregion
#region equality comparison implementations
public override bool Equals(object other)
{
if (!(other is Point2d)) return false;
return Equals((Point2d)other);
}
public bool Equals(Point2d other)
{
return X == other.X && Y == other.Y;
}
public override int GetHashCode()
{
return (int)Math.Round(Y * 31.0 + X, 0); // 31 = some prime number
}
public static bool operator ==(Point2d a1, Point2d a2)
{
return a1.Equals(a2);
}
public static bool operator !=(Point2d a1, Point2d a2)
{
return !a1.Equals(a2);
}
#endregion
}
Point2d is a struct so when you did Point2d p = list[0]; you made a totally separate copy of the object. Your set only changed the copy not the original, you either need to make Point2d a class or add a list[0] = p; after the set.
Bugs like this is why it is recommended to make structs immutable and have no Set methods.
I created the pair class and array class, but I'm lost on how to implement the quicksort algorithm.
I want to do it if ints are same then I should sort by double. I was able to implement quicksort with one value per index of array, but with this I just can't find any resources.
Maybe you guys have some resources or maybe you had the same problem?
By the way I'm trying to implement it with c#.
This is my pair class:
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And my data array class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(1,100), rand.NextDouble());
}
}
public override int integer(int index)
{
return data[index].integer;
}
public override double doubl(int index)
{
return data[index].doubl;
}
public override void Swap(int i, int j)
{
Pair temp = data[i]; // c3 1
data[i] = data[j]; // c3 1
data[j] = temp; // c3 1
}
Your Pair class could implement IComparable<T>, and your quick sort algorithm could be implemented using the CompareTo method.
The IComparable<T> interface:
Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.
You can see the documentation on the CompareTo method to see what the return values mean.
public class Pair : IComparable<Pair>
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int CompareTo(Pair other)
{
if (other == null)
{
return 1;
}
int result = integer.CompareTo(other.integer);
if (result == 0)
{
result = doubl.CompareTo(other.doubl);
}
return result;
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
If you prefer to use the comparison operators, you can implement them in terms of the CompareTo method. The documentation I liked has examples on how to do that.
//sort for integer
var SortedIntegerList = data.OrderBy(x=>x.integer);
//sort for double
var SortedDoubleList = data.OrderBy(x=>x.doubl);
OrderBy for objects uses Quicksort - What Sorting Algorithm Is Used By LINQ "OrderBy"? - so you can use that.
To avoid creating IComparer<Pair> interface you can construct it using Comparer<T>.Create from just comparison delegate:
var sorted = source.OrderBy(x => x, Comparer<Pair>.Create(
(p1, p2) => p1.Integer() - p2.Integer() != 0 ?
p1.Integer() - p2.Integer() :
Math.Sign(p1.Doubl() - p2.Doubl()))).ToList();
I have two interfaces A,B both has same method declarations. I have a class C inheriting from interfaces A,B. I have another class D inheriting from C. Now i want to access the implemented methods in C from D
interface A
{
int add(int x, int y);
int mul(int x, int y);
}
interface B
{
int add(int x, int y);
int mul(int x, int y);
}
public class C : A,B
{
int A.add(int x,int y)
{
return x + y;
}
int A.mul(int x,int y)
{
return 0;
}
int B.add(int x, int y)
{
return x;
}
int B.mul(int x, int y)
{
return y;
}
}
class D : C
{
}
How to access the methods in C from D?
How to access the methods in C from D?
You have to use a reference with a compile-time of the relevant interface. For example:
class D
{
public void FooA()
{
A a = this;
Console.WriteLine(a.mul(...));
}
public void FooB()
{
B b = this;
Console.WriteLine(b.mul(...));
}
}
Of course you don't need the local variable - you can cast:
Console.WriteLine(((A) this).mul(...));
... but it gets a bit ugly.
This is just because you're using explicit interface implementation. If you implemented one of the interfaces implicitly, you could just call the methods directly as normal... but explicit interface implementation only allows a member to be called via that interface.
An explicit interface method invocation should always work
((A)this).mul(1,1);
You can use this code because you have to specify the interface from which you want to use the method (A or B):
((A)this).add(1, 1);
As others already suggested casting is of course one way of doing this. It's quick and simple but if you're going to use it a lot it's annoying. The way out in this case are properties that give access to the members provided by the interface and that conveniently group them thus simplifying their usage:
Easy access without additional casting (you do it only once inside the property getters - see below the C-class):
class Program
{
static void Main(string[] args)
{
C c = new C();
c.As.add(1, 2);
}
}
Interfaces:
public interface A
{
int add(int x, int y);
int mul(int x, int y);
}
public interface B
{
int add(int x, int y);
int mul(int x, int y);
}
C-class:
public class C : A, B
{
// Methods from the A-interface.
public A As { get { return (A)this; } }
// Methods from the B-interface.
public B Bs { get { return (B)this; } }
int A.add(int x, int y)
{
return x + y;
}
int A.mul(int x, int y)
{
return 0;
}
int B.add(int x, int y)
{
return x;
}
int B.mul(int x, int y)
{
return y;
}
}
D-class:
public class D : C
{
public D()
{
base.As.add(1, 2);
base.Bs.add(3, 4);
}
}
Can you check this,
using System;
public class Program
{
public static void Main()
{
D ds=new D(10,12);
int valueAddtion=((A)ds).add(20,122);
int valueMultiplication=((B)ds).mul(20,11);
Console.WriteLine("Mainapplicatin Value of A= " +valueAddtion+" multiplication value= "+valueMultiplication);
}
}
// your code segment here
class D : C
{
public D()
{
int valueAdd=((A)this).add(10,11);
int valueMul=((B)this).mul(20,11);
Console.WriteLine("Addition Value of A= " +valueAdd+" multiplication value= "+valueMul);
}
public D(int x,int y):this()
{
int valueAdd=((A)this).add(x,y);
int valueMul=((B)this).mul(x,y);
Console.WriteLine("Paremeterized Value of A= " +valueAdd+" multiplication value= "+valueMul);
}
}
Output will be,
Addition Value of A= 21 multiplication value= 11
Paremeterized Value of A= 22 multiplication value= 12
Mainapplicatin Value of A= 142 multiplication value= 11
I have an abstract class, Vector, which I would like to overload the operators +,-,*, etc.
I want any derived classes to be able to use these, and get an object back with the same type as the calling object.
I tried with generics, (as follows, in brief), but I couldn't find a legal way to do it:
public static T operator +<T>( T V1, T V2) where T : Vector
{
//some calculation
return new T(args);
}
I then tried to do it just using the base class:
public static Vector operator+(Vector V1, Vector V2)
{
if (V1.Dimension != V2.Dimension)
throw new VectorTypeException("Vector Dimensions Must Be Equal");
double[] ArgList = new double[V1.Dimension];
for (int i = 0; i < V1.Dimension; i++) { ArgList[i] = V1[i] + V2[i]; }
return (Vector)Activator.CreateInstance(V1.GetType(), new object[] { ArgList});
}
If this method is passed in two child objects, it should perform the operation on them, and return a new object of the same heritage.
The problem I ran into with this is that I cannot enforce that all such child classes must have a constructor with the appropriate signature, and I can't call the base constructor to make the object.
What are ways to either (a) Make either of these work, or (b) do this elegantly in another way?
You could declare instance-level abstract methods which your subclass can override:
public abstract class Vector
{
protected abstract Vector Add(Vector otherVector);
public static Vector operator +(Vector v1, Vector v2)
{
return v1.Add(v2);
}
}
public class SubVector : Vector
{
protected override Vector Add(Vector otherVector)
{
//do some SubVector addition
}
}
Might run into some issues especially with multiple subclasses (Will SubVector have to know how to add with SomeOtherSubVectorClass? What if you add ThirdVectorType class?) and perhaps handling null cases. Also, making sure that SubVector.Add behaves the same as SomeOtherSubVectorClass.Add when it comes to commutative operations.
EDIT: based on your other comments, you could so something like:
public class Vector2D : Vector
{
public double X { get; set; }
public double Y { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector2D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = otherVector3D.Z };
//handle other cases
}
}
public class Vector3D : Vector
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector3D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y, Z = this.Z };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = this.Z + otherVector3D.Z };
//handle other cases
}
}
EDITx2:
Given your latest comment, perhaps your should just maintain an internal array/matrix and just do generic matrix math. Your subclasses can expose X/Y/Z property wrappers against the array indicies:
public class Vector
{
protected double[] Values;
public int Length { get { return Values.Length; } }
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
return new Vector() { Values = newValues };
}
}
}
public class Vector2D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
}
public class Vector3D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
public double Z
{
get { return Values[2]; }
set { Values[2] = value; }
}
}
EDITx3: Based on your latest comment, I guess you could implement operator overloads on each subclass, do the shared logic in a static method (say in the base Vector class), and somewhere do a switch/case check to provide a specific subclass:
private static Vector Add(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
switch (newValues.Length)
{
case 1 :
return new Vector1D() { Values = newValues };
case 2 :
return new Vector2D() { Values = newValues };
case 3 :
return new Vector3D() { Values = newValues };
case 4 :
return new Vector4D() { Values = newValues };
//... and so on
default :
throw new DimensionOutOfRangeException("Do not support vectors greater than 10 dimensions");
//or you could just return the generic Vector which doesn't expose X,Y,Z values?
}
}
}
Then your subclasses would have:
public class Vector2D
{
public static Vector2D operator +(Vector2D v1, Vector2D v2)
{
return (Vector2D)Add(v1, v2);
}
}
public class Vector3D
{
public static Vector3D operator +(Vector3D v1, Vector3D v2)
{
return (Vector3D)Add(v1, v2);
}
}
Some duplication, but I don't see a way around it off the top of my head to allow the compiler to do this:
Vector3 v1 = new Vector3(2, 2, 2);
Vector3 v2 = new Vector3(1, 1, 1);
var v3 = v1 + v2; //Vector3(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y + ", " + v3.Z);
or for other dimensions:
Vector2 v1 = new Vector2(2, 2);
Vector2 v2 = new Vector2(1, 1);
var v3 = v1 + v2; //Vector2(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y); // no "Z" property to output!
What about having an abstract method called Add() that operator+ just acts as a wrapper for? ie, "return v1.Add(v2)". This would also enable you to define interfaces which non-Vector classes can constrain their code to, enabling to perform math-like operations (since generic code can't see/touch operators like +, -, etc for any type).
The only constructor you can code with in a generic method is the default (ie, parameter-less) constructor, which you have to specify in the generic constraints for the method/type.
Five years later I had the exact same problem, only I was calling them Ntuples, not vectors. Here is what I did:
using System;
using System.Collections.Generic;
public class Ntuple{
/*parent class
has an array of coordinates
coordinate-wise addition method
greater or less than in dictionary order
*/
public List<double> Coords = new List<double>();
public int Dimension;
public Ntuple(List<double> Input){
Coords=Input;
Dimension=Input.Count;
}//instance constructor
public Ntuple(){
}//empty constructor, because something with the + overload?
public static Ntuple operator +(Ntuple t1, Ntuple t2)
{
//if dimensions don't match, throw error
List<double> temp = new List<double>();
for (int i=0; i<t1.Dimension; i++){
temp.Add(t1.Coords[i]+t2.Coords[i]);
}
Ntuple sum = new Ntuple(temp);
return sum;
}//operator overload +
public static bool operator >(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]>other.Coords[i]) {return true;}
}
return false;
}
public static bool operator <(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]<other.Coords[i]) {return true;}
}
return false;
}
}//ntuple parent class
public class OrderedPair: Ntuple{
/*
has additional method PolarCoords, &c
*/
public OrderedPair(List<double> Coords) : base(Coords){}
//instance constructor
public OrderedPair(Ntuple toCopy){
this.Coords=toCopy.Coords;
this.Dimension=toCopy.Dimension;
}
}//orderedpair
public class TestProgram{
public static void Main(){
List<double> oneCoords=new List<double>(){1,2};
List<double> otherCoords= new List<double>(){2,3};
OrderedPair one = new OrderedPair(oneCoords);
OrderedPair another = new OrderedPair(otherCoords);
OrderedPair sum1 = new OrderedPair(one + another);
Console.WriteLine(one.Coords[0].ToString()+one.Coords[1].ToString());
Console.WriteLine(sum1.Coords[0].ToString()+sum1.Coords[1].ToString());
bool test = one > another;
Console.WriteLine(test);
bool test2 = one < another;
Console.WriteLine(test2);
}
}
}//namespace ntuples
The short version of the question - why can't I do this? I'm restricted to .NET 3.5.
T[] genericArray;
// Obviously T should be float!
genericArray = new T[3]{ 1.0f, 2.0f, 0.0f };
// Can't do this either, why the hell not
genericArray = new float[3]{ 1.0f, 2.0f, 0.0f };
Longer version -
I'm working with the Unity engine here, although that's not important. What is - I'm trying to throw conversion between its fixed Vector2 (2 floats) and Vector3 (3 floats) and my generic Vector<> class. I can't cast types directly to a generic array.
using UnityEngine;
public struct Vector<T>
{
private readonly T[] _axes;
#region Constructors
public Vector(int axisCount)
{
this._axes = new T[axisCount];
}
public Vector(T x, T y)
{
this._axes = new T[2] { x, y };
}
public Vector(T x, T y, T z)
{
this._axes = new T[3]{x, y, z};
}
public Vector(Vector2 vector2)
{
// This doesn't work
this._axes = new T[2] { vector2.x, vector2.y };
}
public Vector(Vector3 vector3)
{
// Nor does this
this._axes = new T[3] { vector3.x, vector3.y, vector3.z };
}
#endregion
#region Properties
public T this[int i]
{
get { return _axes[i]; }
set { _axes[i] = value; }
}
public T X
{
get { return _axes[0];}
set { _axes[0] = value; }
}
public T Y
{
get { return _axes[1]; }
set { _axes[1] = value; }
}
public T Z
{
get
{
return this._axes.Length < 2 ? default(T) : _axes[2];
}
set
{
if (this._axes.Length < 2)
return;
_axes[2] = value;
}
}
#endregion
#region Type Converters
public static explicit operator Vector<T>(Vector2 vector2)
{
Vector<T> vector = new Vector<T>(vector2);
return vector;
}
public static explicit operator Vector<T>(Vector3 vector3)
{
Vector<T> vector = new Vector<T>(vector3);
return vector;
}
#endregion
}
"Generic" means "works with any type".
Your example code is not generic, because it only works if and only if T is float.
While you can't convert a Vector2D to a Vector<T>, you can, of course, convert a Vector2D to a Vector<float>. Add a Convert method to Vector2D or provide a set of extension methods like this:
public static class VectorExtensions
{
public static Vector<float> ToGenericVector(this Vector2D vector)
{
return new Vector<float>(vector.X, vector.Y);
}
public static Vector2D ToVector2D(this Vector<float> vector)
{
return new Vector2D(vector.X, vector.Y);
}
}
Usage:
Vector<float> v = new Vector<float>(3, 5);
Vector2D v2 = v.ToVector2D();
if T is defined as float, via Vector<T> as Vector<float> then this will work (on a restricted T), but if you just want a local conversion:
var genericArray = new float[3]{ 1.0f, 2.0f, 0.0f };
Of course, this restricts T to being a float anyway (the compiler can't convert just anything to T and knows this), it looks like you should replace T with float in the whole class if that's the case, are you dealing with non-float vectors?
In that case you need something like:
var genericArray = new T[3]{ X, Y, Z };
You cannot imply the type of a generic parameter from within a method.
And, as I stated before, your posted code does not represent a valid usage of Generic type parameters.
The generic parameter is to be defined in the class or method signature.
public class Class1<T>
{
public T[] Method(params T[] args)
{
return args;
}
}
public class Demo
{
public Demo()
{
var c1 = new Class1<float>();
float[] result = c1.Method(1.1f, 2.2f);
}
}
You said:
// This doesn't work
this._axes = new T[2] { vector2.x, vector2.y };
The following works (since everything can be converted to object, and the subsequent conversion from object to T is permitted but may fail at runtime if the types aren’t compatible, or in this case if unboxing cannot be performed):
this._axes = new T[2] { (T)(object)vector2.x, (T)(object)vector2.y };
That said, it makes absolutely no sense to make the class generic.