Problem with Interface Implementation When using Inheritance - c#

I have created IShallowCloneable interface to create shallow copy of class for All of my class but with inheritance it is not working properly.
Look at Main method, node2 is returning Point3D object Instead of Node.
Details
Point2D is Base Class
Point3D Class Derived from Point2D Class
Node
Class Derived from Point3D Class
using System;
namespace ConsoleAppTest
{
internal static class Program
{
private static void Main()
{
try
{
var node = new Node(1, 0, 0, 0);
var node2 = node.ShallowClone();//this code is returing Point3D Object instead of Node
}
catch (Exception)
{
throw;
}
finally
{
Console.ReadLine();
}
}
}
public interface IShallowCloneable<T>
{
T ShallowClone();
}
public class Point2D : IShallowCloneable<Point2D>
{
public int X { get; set; }
public int Y { get; set; }
public Point2D()
{
}
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public Point2D ShallowClone()
{
return new Point2D(X, Y);
}
}
public class Point3D : Point2D, IShallowCloneable<Point3D>
{
public int Z { get; set; }
public Point3D()
{
}
public Point3D(int x, int y,int z):base(x,y)
{
Z = z;
}
new public Point3D ShallowClone()
{
return new Point3D(X, Y,Z);
}
}
public class Node:Point3D, IShallowCloneable<Node>
{
public int Id { get; set; }
public Node()
{
}
public Node(int id,int x, int y, int z):base(x,y,z)
{
Id = id;
}
Node IShallowCloneable<Node>.ShallowClone()
{
return new Node(Id,X, Y, Z);
}
}
}

Because for Node you've implemented IShallowCloneable<Node> as explicit interface, so it will work only if you cast to it:
// prints Node
Console.WriteLine(((IShallowCloneable<Node>)node).ShallowClone().GetType().Name);
If you want it to behave as Point3D you need to implement it as you do there ( hiding inherited Point2D implementation with new keyword).

so if you want to use ShallowClone method Explicitly without changing Class
var node = new Node(1, 0, 0, 0);
var node2 = ((IShallowCloneable<Node>)node).ShallowClone();
or if you want implicit implementation you have to Modify ShallowClone() method implementation in Node Class like this
new public Node ShallowClone()
{
return new Node(Id, X, Y, Z);
}
Additional Reference
C# Interfaces. Implicit implementation versus Explicit implementation

Related

IComparer C# + generics

How I can write make method Compare in RoomComparerByVolume ?
"Define a generic class RoomComparerByVolume<> implementing IComparer interface.
Impose a constraint on the type argument so that it should implement the IShape interface.
This comparer should perform comparison of rooms by room volume."
public interface IShape
{
public double Area()
{
return 0;
}
}
public class Rectangle : IShape
{
public double Length { get; set; }
public double Width { get; set; }
public double Area()
{
return Length * Width;
}
}
public class Trapezoid : IShape
{
public double Length1 { get; set; }
public double Length2 { get; set; }
public double Width { get; set; }
public double Area()
{
return (Length1 + Length2) * Width / 2;
}
}
public class Room<T> where T : IShape, ICloneable, IComparable
{
public double Height { get; set; }
public T Floor;
public double Volume()
{
return Height * Height;
}
public object Clone()
{
return new Room<T> { Height = this.Height, Floor = this.Floor };
}
public int CompareTo(object o)
{
Room<T> r = o as Room<T>;
if (r != null)
return this.Volume().CompareTo(r.Volume());
else
throw new Exception("Unable to compare");
}
}
public class RoomComparerByVolume<T> : IComparer<T> where T : IShape
{
}
Your question is a bit unclear. If compare "by room volume" means in fact compare Area() values
and you want to imeplement a corresponding comparer, you can put something like this
public sealed class ShapeComparerByArea<T> : IComparer<T> where T : IShape
{
public int Compare(T left, T right)
{
if (ReferenceEquals(left, right))
return 0;
if (left == null)
return 1;
if (right == null)
return -1;
return left.Area().CompareTo(right.Area());
}
}
If you want to define comparable Room class (which has Shape Floor) you can put it as
public class Room : IComparable<Room> {
public Room(IShape floor, double height) {
Floor = floor ?? throw new ArgumentNullException(nameof(floor));
Height = height > 0
? height
: throw new ArgumentOutOfRangeException(nameof(height));
}
public IShape Floor { get; }
public double Height { get; }
public double Volume => Floor.Area() * Height;
public int CompareTo(Room other) {
if (ReferenceEquals(this, other))
return 0;
if (other is null)
return 1;
return Volume.CompareTo(other.Volume);
}
}
Finally, RoomComparerByVolume can be
public sealed class RoomComparerByVolume : IComparer<Room> {
public int Compare(Room left, Room right) {
if (ReferenceEquals(left, right))
return 0;
if (left == null)
return 1;
if (right == null)
return -1;
return left.Volume.CompareTo(right.Volume);
}
}
Demo:
Room myRoom = new Room(
new Trapezoid() { Length1 = 5, Length2 = 7, Width = 3},
2.8);
Room myOtherRoom = new Room(
new Rectangle() { Length = 3, Width = 4 },
2.5);
Console.WriteLine(myRoom.CompareTo(myOtherRoom));
RoomComparerByVolume comparer = new RoomComparerByVolume();
Console.WriteLine(comparer.Compare(myRoom, myOtherRoom));
I would assume that the desired declaration should look like
public class RoomComparerByVolume<T> : IComparer<Room<T>> where T : IShape, ICloneable, IComparable{
public int Compare(Room<T> left, Room<T> right) {
...
}
That way you can compare the two rooms. But note that the two rooms need to be the same shape using this method. Also note that you need to use the same generic constraints as you are using for Room<T>.
Also note that in many cases you do not need to create a specific comparer type. Often you can use a delegate to do the actual comparison:
Comparer<Room<Trapezoid>>.Create((l, r) => l.Volume().CompareTo(r.Volume));

how to Implement this Abstract Class/properties logic by Interface in C#?

I have a abstract Class figures which contains Abstract properties
and I am Overriding them in Derived class Rectangle and
Square. Now, iI want to implement this with Interface. But I can't use
constructor and neither I can't Declare the Variable inside the
Interface. So, how to implement this using Interface where Figures Should be Interface and Square and Rectangle should be class?
abstract class Figures
{
int Width;
int _cs;
public Figures(int Width)
{
CS = Width;
}
public abstract int getarea
{
get;
}
public abstract int getperm
{
get;
}
public abstract int CS
{
set;
}
public abstract void display();
}
class Square : Figures
{
int _CsS;
public Square(int c) : base(c)
{
}
public override int getarea
{
get
{
return (_CsS * _CsS);
}
}
public override int getperm
{
get
{
return (2 * _CsS * _CsS);
}
}
public override int CS
{
set
{
_CsS = value;
}
}
public override void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
}
class Rectangle : Figures
{
int H;
int _csr;
public Rectangle(int H, int W) : base(W)
{
this.H = H;
}
public override int getarea
{
get
{
return H * _csr;
}
}
public override int getperm
{
get
{
return 2 * H * _csr;
}
}
public override int CS
{
set
{
_csr = value;
}
}
public override void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
}
so how to implement this using Interface
By definition, an interface won't let you implement anything. You can only specify things.
So you will have to remove the ctor and the fields from the interface IFigures and re-implement them in every class. You could reuse an implementation with a abstract class FiguresBase: IFigures but that's not always the best design.
It all depends on why you want the interface and how you will use it.
You can do something like this:
interface IFigures
{
int getarea
{
get;
}
int getperm
{
get;
}
int CS
{
set;
}
void display();
}
Thenk you can implement this interface from your classes and do your logic inside the class itself. So instead of putting the properties logic inside of your abstract class you will have to write them in your child classes.
class Square : IFigures
{
int _CsS;
public Square(int c)
{
CS = c;
}
public int getarea
{
get
{
return (_CsS * _CsS);
}
}
public int getperm
{
get
{
return (2 * _CsS * _CsS);
}
}
public int CS
{
set
{
_CsS = value;
}
}
public void display()
{
Console.WriteLine("area={0} and perimeter={1}", getarea, getperm);
}
//here you have implemented properties
}
Your abstract class is a good thing. It lets you re-use code.
Interfaces (i.e. contracts) are also good if you want to achieve a loosely coupled system.
You can use abstract classes and interfaces together, to achieve both code reusability and loosely coupled parts.
public interface IFigures
{
int getarea();
}
public abstract class Figures : IFigures
{
public abstract int getarea();
//opportunity for code reuse
protected int getarea_internal()
{
throw new NotimplementedExcpetion();
}
}
public class Square : Figures
public class Rectangle: Figures
here is the answer
with class Diagram
Class Diagram of the Program
interface IFigures
{
int Getarea
{
get;
}
int GetPerm
{
get;
}
int CS
{
//get;
set;
}
}
abstract class Figures:IFigures
{
int _Cs;
public Figures( int _Cs)
{
CS = _Cs;
}
public abstract int Getarea
{
get;
}
public abstract int GetPerm
{
get;
}
public abstract int CS
{
//get;
set;
}
public abstract void display();
}
class Circle:Figures
{
int _r, _csc;
public Circle(int _r):base(_r)
{
CS = _r;
}
public override int Getarea
{
get
{
return (_r * _r);
}
}
public override int GetPerm
{
get
{
return (2* _csc * _csc);
}
}
public override void display()
{
Console.WriteLine("area of Circle={0}", (_r * _r));
Console.WriteLine("perimeter of rectangle={0}", (2 * _r * _r));
}
public override int CS
{
//get
//{
// return _csc;
//}
set
{
_csc = value;
}
}
}
class Rectangle:Figures
{
int _L, _csr;
public Rectangle(int _L,int _W):base(_W)
{
this._L = _L;
CS = _W;
}
public override int Getarea
{
get
{
return _csr * _L;
}
}
public override int GetPerm
{
get
{
return (2* _csr * _L);
}
}
public override void display()
{
Console.WriteLine("area of rectangle={0}", (_csr * _L));
Console.WriteLine("perimeter of rectangle={0}", (2* _csr * _L));
}
public override int CS
{
//get
//{
// return _csr;
//}
set
{
_csr = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Figures f = new Rectangle(3, 4);
f.display();
//f.CS = 5;
f.display();
Console.ReadKey();
}
}

Covariant Collection not working

Sorry if the question is redundant, but I couldn't find a solution for my particular case.
Please consider this block of code:
public interface IPoint {}
public class GazePoint : IPoint {}
public Point AvgPoint(IEnumerable<IPoint> locations) {}
List<GazePoint> gazePoints = new List<GazePoint>();
//...
// this doesn't work:
Point avg = AvgPoint(gazePoints);
Could you please explain why it doesn't work (I was assuming C# 4.0 has solved this issue) and how can I change the signature of AvgPoint() method to make it possible to receive different implementations of IPoint. (I don't want to cast gazePoints collection to another type of collection, because it is in a big loop, and I'm concern about the performance.
[Update]: I had defined GazePoint as struct, and that was the source of problem. Still, I don't know why struct is not working here.
I'm not sure what the exact problem is you're having, but here's how it worked for me:
First, some actual class implementations:
public interface IPoint
{
int X { get; set; }
int Y { get; set; }
}
public class Point : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public Point()
{
}
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public class GazePoint : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public GazePoint()
{
}
public GazePoint(int x, int y)
{
X = x;
Y = y;
}
}
Then an actual AvgPoint method implementation:
public static Point AvgPoint(IEnumerable<IPoint> locations)
{
if (locations == null || !locations.Any()) return new Point(0, 0);
return new Point((int) locations.Average(l => l.X),
(int) locations.Average(l => l.Y));
}
And finally a few tests:
public static void Main()
{
var points = new List<Point>
{
new Point(1, 2),
new Point(3, 4)
};
var gazePoints = new List<GazePoint>
{
new GazePoint(1, 2),
new GazePoint(3, 4)
};
Point avgPoint = AvgPoint(points);
Point avgGazePoint = AvgPoint(gazePoints);
Console.WriteLine("Average Point = {0}, {1}", avgPoint.X, avgPoint.Y);
Console.WriteLine("Average GazePoint = {0}, {1}", avgGazePoint.X, avgGazePoint.Y);
}
If your goal is to have the method return the average in the same type that was passed in, you can make it generic like so:
public static T AvgPoint<T>(IEnumerable<T> locations) where T : IPoint, new()
{
if (locations == null || !locations.Any()) return new T {X = 0, Y = 0};
return new T {X = (int) locations.Average(l => l.X),
Y = (int) locations.Average(l => l.Y)};
}

How to return derivered type from method declared in base type

I've a method in a base class that should return self instance of type as derivered type. For example:
class A
{
public string X { get; set; }
public A SetX(string x)
{
this.X = x;
return this;
}
}
class B:A
{
public string Y { get; set; }
public B SetY(string y)
{
this.Y = y;
return this;
}
}
Then I want to call methods fluently as below:
B b = new B();
b.SetX("x")
.SetY("y");
But here SetX returns type of A, and A has'nt any method named SetY. How can I design such functionalty?
One option would be to declare SetX as a generic extension method:
public static T SetX<T>(this T a, string x) where T : A
{
a.X = x;
return a;
}
You can then call it like this:
var newB = b.SetX("foo"); // returns type B
There are a couple different things you could do to achieve this.
The first is to use generics, using a type parameter to designate the real type of the instance:
public class A<T> where T:A<T>
{
public string X { get; private set; }
public T SetX(string x)
{
X = x;
return (T) this;
}
}
public class B<T> : A<T>
where T : B<T>
{
public string Y { get; private set; }
public T SetY(string y)
{
Y = y;
return (T) this;
}
}
public class A : A<A>
{
}
public class B : B<B>
{
}
The second is to, in your B class, hide the method from A using the new keyword, like so:
class A
{
public string X { get; set; }
public A SetX(string x)
{
this.X = x;
return this;
}
}
class B : A
{
public string Y { get; set; }
public new B SetX(string x)
{
return (B) base.SetX(x);
}
public B SetY(string y)
{
this.Y = y;
return this;
}
}
use protected:
protected string X { get; set; }
protected A SetX(string x)
{
this.X = x;
return this;
}
This one worked for me:
(b.SetX("1") as B).SetY("2");

Get the index in a multidimensional class

Sorry for the title i will put here an example of what i want to accomplish:
namespace mdclass
{
class pClass
{
static void Main()
{
tiles<int> tl = new tiles<int>();
tl[0].X = 0;
}
}
class tiles<T> : List<T>
{
public int X
{
//get/set the X-coordonate
}
public int Y
{
//get/set the Y-coordonate
}
}
}
how can i transfer the [0] from the tl[0] in the public int X and work with it?
Create a class for x and y coordinates:
public sealed class Point {
public int X { get; set; }
public int Y { get; set; }
}
Use the Point class to store the coordinates into the list:
public sealed class Program {
public static void Main() {
var tiles = new List<Point>();
tiles.Add(new Point { X = 5, Y = 10 });
tiles[0].X = 15;
}
}
Could you not just make tl public?
Then myInt = mypClass.tl[0].X
A data heirachy like this might work for you (no time to add actual code, sorry!). Then you could implement appropriate getters and setters.
Public class Grid {
List<Row>
}
Public class Row{
List<Point>
}
Public Class Point{
public int X { get; set; }
public int Y { get; set; }
}

Categories

Resources