Use function of logical parent - c#

maybe my question is totally stupit but I'm trying to do my best.
All I want to do is to use a function/property of a parent element.
I have prepared a simple example with no sense:
class A
{
public List<B> myBs = new List<B>();
public int CountMyBs()
{
return myBs.Count;
}
}
class B
{
//here i would like to use "CountMyBs()"
}
Thank you!
Edit: I think I have to provide you some more information.
My user is able to drag a value to a canvas.
My canvas is in a list of a parent class.
Now my canvas wants to know if any other canvas in the list has already the same value.
My idea of realizing:
User does a drag --> Canvas gets an event --> Canvas ask parent class if any other Canvas has already the same value --> decide what to do.
I will post a mor detailed example tomorrow!

You need something like this:
class A : FrameworkElement
{
public int CountMyBs() {}
}
class B : FrameworkElement
{
public void Foo()
{
var parent = LogicalTreeHelper.GetParent(this) as A;
if (parent != null)
{
//here i would like to use "CountMyBs()"
parent.CountMyBs();
}
}
}

You can pass the instance of A through the constructor of B:
class B
{
private readonly A a;
public B(A a)
{
this.a = a;
}
public int Foo() //Example use
{
return 1 + a.CountMyBs();
}
}
class A
{
public List<B> myBs = new List<B>();
public A()
{
myBs.Add(new B(this)); //Pass the current A to B
}
public int CountMyBs()
{
return myBs.Count;
}
}
But it looks like a bad code smell to me. Unless you have a very specific use case for this, I'd avoid having a child class knowing its parent class only to access a list of itself.
You could simply call your Bs from A, with your method result as a parameter. Feels more natural. It could look like :
class A
{
public List<B> myBs = new List<B>();
public A()
{
var someB = new B();
myBs.Add(someB);
someB.Foo(CountMyBs());
}
public int CountMyBs()
{
return myBs.Count;
}
}
class B
{
public int Foo(int count) //Example use
{
return 1 + count;
}
}

Related

nested classes and interfaces

(I really struggled with coming up with a good title for this question, if anyone wants to help out with that..)
So I'm having an issue designing something. Essentially I have a class A, which is composed of an array of objects of type B. I only want the interface of class A to be exposed, and want to keep class B essentially hidden to any user. I want to be able to perform operations on type B and its data, but only through class A's interface/methods calling methods of an instance of B. The part where it gets tricky is that I want to create a method that performs operations on members of type B, but I wanted to implement an interface and then have a class that implements that interface because I want my user to be able to create their own implementation of this method. I was thinking of doing somtehing like:
public class A
{
B[] arr;
C c;
public A(C c)
{
arr = new B[100];
this.c = c;
}
public void method1()
{
var b = new B();
b.someMethodofb(c); // pass c to the method of b
}
private class B
{
someMethodOfb(C c)
{
}
}
}
public class C : Interface1
{
public void method(B b)
{
//interface method we have implemented
}
}
I made the class B private because I only want class A to be publicly available so anything that happens to class B happens through class A, which is also why I nested B within A. But since class B is private, will I be able to use it as a parameter for the method of my class C? The method of Interface1 implemented is going to affect the internal implementation of how B performs someMethodOfb, which is why I think I need to pass it in to be able to maintain the hidden nature of class B. Could there be a better way for me to design this and be able to achieve the goals I set out in the first paragraph?
I would suggest you add another interface for the public known side of B, have B implement that interface and have C's method(s) use the interface.
public interface IC {
void method(IB b);
}
public interface IB {
int Priority { get; set; }
int Urgency { get; set; }
}
public class A {
B[] arr;
IC c;
public A(C c) {
arr = new B[100];
this.c = c;
}
public void method1() {
var r = (new Random()).Next(100);
arr[r].someMethodOfB(c); // pass c to the method of b
}
private class B : IB {
public int Priority { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public int Urgency { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
internal void someMethodOfB(IC aC) {
aC.method(this);
throw new NotImplementedException();
}
}
}
public class C : IC { // user implements
public void method(IB b) {
if (b.Priority > 10 || b.Urgency > 10)
; // do something with BI using b
throw new NotImplementedException();
}
}
Now the user of the classes needs to know IC so they can create C and they need to know IB so they can write the body of the methods in C, but they don't need to know all of B or have access to B.
Let's use concrete examples :)
Say, we have three classes: Customer, Order, and OrderProcessor. Customer and Order are entities representing a customer and an order respectively, while OrderProcessor will process an order:
public interface IOrderProcessor
{
void ProcessOrder(IOrder order);
}
public interface IOrder
{
void FinalizeSelf(IOrderProcessor oProc);
int CustomerId {get; set;}
}
public class Customer
{
List<IOrder> _orders;
IOrderProcessor _oProc;
int _id;
public Customer(IOrderProcessor oProc, int CustId)
{
_oProc = oProc;
_orders = new List<IOrder>();
_id = CustId;
}
public void CreateNewOrder()
{
IOrder _order = new Order() { CustomerId = _id };
_order.FinalizeSelf(_oProc);
_orders.Add(_order);
}
private class Order : IOrder
{
public int CustomerId {get; set;}
public void FinalizeSelf(IOrderProcessor oProcessor)
{
oProcessor.ProcessOrder(this);
}
}
}
public class ConcreteProcessor : IOrderProcessor
{
public void ProcessOrder(IOrder order)
{
//Do something
}
}

C#: Calling parent (Base) constructor from child's constructor body

I have an abstract class Parent and a derived class Child. I know that I can call Parent's constructor inside Child's constructor in the following way:
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
}
class Child : Parent
{
public Child(int i) : base(i)
{
}
}
However, I don't want to pass some parameters to the Parent constructor right away. I would like to perform some calculations and then call Parent's constructor using the result of such calculation as input parameters. The code "would look" something like this:
public class Child : Parent
{
public Child(int i)
{
int calculation = i * 2; // Complicated operation
base(calculation); // This line will break
}
}
The second snippet is not valid C# code. Is there any way of postponing the call to Parent's constructor to mimic the sentiment expressed on the second code snippet?
This would do the same trick assuming u can access the properties directly
abstract class Parent
{
protected int i;
protected Parent()
{
//default constructor
}
}
class Child : Parent
{
public Child(int i)
{
Int calculation = i * 2
base.i = calculation
}
}
however if u cant do that because of restricted access to the properties my personal preference is to outsource the logic of the calculation in separate function and call the base class like following:
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
}
class Child : Parent
{
public Child(int i) : base(Child.dosomework(i))
{
}
public static int dosomework(int i){
int calculation = i * 2
return calculation
}
}
abstract class Parent
{
protected int i;
protected Parent(int i)
{
this.i = i;
}
protected Parent(Func<int> param)
{
i = param();
}
}
class Child : Parent
{
public Child(int i) : base(() => i * 2)
{
}
}
Create a static method and use base(MyStaticMethod(params))
If you were allowed to call a base constructor in the child class in that way, you can face weird problems in your programs. Means that you can leave that instance in an inconsistent state because you could make a try-catch to handle some input-parameter errors and bypass the constructor. That is not the idea, imagine if you were allowed to create a Date in that way.
class MyDate : DateTime
{
public int(int year, int month, int day)
{
try
{
base(-1, -1, -1)
}
catch
{
}
}
}
The funny thing is that Java allows that with the super keyword.
The point of a constructor is to construct the instance, i.e. get it into a valid state. It should do that and nothing else. And if your class can exist without having i set already, then the act of setting i is not essential to its validity and therefore doesn't belong in a constructor.
Perhaps you don't want inheritance, you want composition.
class Inner
{
protected readonly int _i;
public Inner(int i)
{
_i = i;
}
}
class Outer
{
protected Inner _inner = null;
public Outer()
{
//Construct
}
public void SetI(int i)
{
_inner = new Inner(i); //Call constructor of Inner
}
}

Create a constructor with parent class as parameter

I don't know how to define my question (probably already asked but didn't found it).
I want to create a constructor for a class B inherited from A taking a B object as parameter used to be a copy of it.
There can be something like this :
class B : A
{
public String NewField;
public B(A baseItem, String value)
{
// Create new B to be a copy of baseItem
???; // something like : this = baseItem
// Add new field
NewField = value;
}
}
Objective is to create an object B which is the exact copy of an A object with on filed more.
Use the base keyword to call the parent class constructor, giving your parent class instance as a parameter. Then create a copy constructor in your parent, and you're done.
class A
{
public A(A a)
{
// Copy your A class elements here
}
}
class B : A
{
public String NewField;
public B(A baseItem, String value)
: base(baseItem)
{
NewField = value;
}
}
You could implement a CopyProperties method, which will copy the properties values.
using System;
public class A
{
public string Filename {get; set;}
public virtual void CopyProperties(object copy)
{
((A)copy).Filename = this.Filename;
}
}
public class B : A
{
public int Number {get;set;}
public override void CopyProperties(object copy)
{
base.CopyProperties(copy);
((B)copy).Number = this.Number;
}
}
public class Program
{
public static void Main()
{
B b = new B { Filename = "readme.txt", Number = 42 };
B copy = new B();
b.CopyProperties(copy);
Console.WriteLine(copy.Filename);
Console.WriteLine(copy.Number);
}
}

Inherit in generic classes C#

My brain is gonna to explode. :) So I would like to get help from you.
Please, think about my question like about just programmer puzzle. (Actually. perhaps it is very easy question for you, but not for me.)
It is needed to create array of objects. For example List where T is class. (I will describe Class T below). Also it is needed create “container” that will contain this array and some methods for work with this array. For example Add(), Remove(int IndexToRemove).
Class T must have field "Container", this way each elements of our array would be able to know where is it contained and has access its container's fields and methods. Notice, that in this case Class T should have type parameter. Indeed, it is not known beforehand which container's type is used.
Let us denote this class container as A and class element (class T) as AUnit.
Code:
class Program
{
static void Main(string[] args)
{
A a = new A();
a.Add();
a.Units[0].SomeField +=100;
Console.ReadKey();
}
}
class A
{
public List<AUnit> Units;
public A()//ctor
{
Units = new List<AUnit>();
}
public void Add()
{
this.Units.Add(new AUnit(this));
}
}
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
}
Public fields should be protected or private of course, but let think about this later.
You can ask “why we create public A Container field in AUnit”? We create field public string Name{get;private set;} (actually property but nevermind). And also we would like to be able to change value of this field for example method [Class AUnit] public bool Rename(string newName)();. The main idea of this method is changing Name field only that case if no one element in array (public List Units; ) has the same name like newName. But to achieve this, Rename method has to have access to all names that is currently used. And that is why we need Container field.
Code of extended version AUnit
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (AUnit unt in this.Container.Units)
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
Ok. If you still read it let's continue. Now we need to create Class B and class BUnit which will be very similar like Class A and Class Aunit. And finally the main question of this puzzle is HOW WE CAN DO IT? Of course, I can CopyPaste and bit modify A and AUnit and create this code.
class B
{
public List<BUnit> Units; //Only Type Changing
public B()//ctor Name changing...
{
Units = new List<BUnit>();//Only Type Changing
}
public void Add()
{
this.Units.Add(new BUnit(this));//Only Type Changing
}
}
class BUnit
{
public int SomeField;
public B Container;//Only Type Changing
public string Name { get; private set; }
public A a; //NEW FIELD IS ADDED (just one)
public BUnit(B container) //Ctor Name and arguments type changing
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
this.a=new A(); //New ROW (just one)
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (BUnit unt in this.Container.Units) //Only Type Changing
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
And I can to use this classes this way.
static void Main(string[] args)
{
B b = new B();
b.Add();
b.Units[0].a.Add();
b.Units[0].a.Units[0].SomeField += 100;
bool res= b.Units[0].a.Units[0].Rename("1");
res = b.Units[0].a.Units[0].Rename("1");
Console.ReadKey();
}
This construction is can be used to create “non-homogeneous trees”.
Help, I need somebody help, just no anybody…. [The Beatles]
I created B and BUnit using CopyPaste.
But how it can be done using “macro-definitions” or “Generic”, inherit or anything else in elegant style? (C# language)
I think that there is no reason to describe all my unsuccessful attempts and subquestions. Already topic is too long. : )
Thanks a lot if you still read it and understand what I would like to ask.
You need to implement a base type, lets call it UnitBase, with all common functionality. I'd structure your code the following way:
Create an interface for your container, this way you can change implementation to more performant solutions without modifying the elements you will be adding to the container.
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
}
Following the idea stated in 1, why not make the search logic belong to the container? It makes much more sense, as it will mostly depend on how the container is implemented:
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
bool Contains(string name);
}
A specific implementation of IContainer could be the following:
public class Container : IContainer
{
public Container()
{
list = new List<UnitBase>();
}
private List<UnitBase> list;
public Q Add<Q>() where Q: UnitBase, new()
{
var newItem = Activator.CreateInstance<Q>();
newItem.SetContainer(this);
list.Add(newItem);
return newItem;
}
public IEnumerable<UnitBase> Units => list.Select(i => i);
public bool Contains(string name) =>
Units.Any(unit => unit.Name == name);
}
Create a base class for your AUnit and BUnit types condensing all common functionality:
public abstract class UnitBase
{
protected UnitBase()
{
}
public IContainer Container { get; private set; }
public int SomeField;
public string Name { get; private set; }
public void SetContainer(IContainer container)
{
Container = container;
}
public bool Rename(String newName)
{
if (Container.Contains(newName))
return false;
this.Name = newName; //No need to use String.Copy
return true;
}
}
Implement your concrete types:
public class BUnit : UnitBase
{
public int SpecificBProperty { get; private set; }
public BUnit()
{
}
}
Shortcomings of this approach? Well, the container must be of type <UnitBase>, I've removed the generic type because it really wasn't doing much in this particular case as it would be invariant in the generic type.
Also, keep in mind that nothing in the type system avoids the following:
myContainer.Add<BUnit>();
myContainer.Add<AUnit>();
If having two different types in the same container is not an option then this whole set up kind of crumbles down. This issue was present in the previous solution too so its not something new, I simply forgot to point it out.
InBetween , I am very thankful to you for your advices. Actually I can't say that I understood your answer in full, but using your ideas I have done what I want.
Looks like my variant works well. However I would like to hear your (and everyone) opinions about code described below. The main goal of this structure is creating non-homogeneous trees. So could you estimate it from this side.
First of all. We need to create interfaces for both classes. We describe there all "cross-used" functions.
public interface IUnit<T>
{
string Name { get;}
void SetContainer(T t);
bool Rename(String newName);
}
public interface IContainer
{
bool IsNameBusy(String newName);
int Count { get; }
}
Next. Create Base for Unit Classes for future inheritance. We will use in this inheritors methods from Container Base so we need generic properties and IUnit interface.
class UnitBase<T> : IUnit<T> where T : IContainer
Unfortunately I don't know yet how to solve the problem with Constructor parameters. That is why I use method
SetContainer(T container).
Code:UnitBase
class UnitBase<T> : IUnit<T> where T : IContainer
{
protected T Container;
public string Name { get; private set; }
public UnitBase()
{
this.Name = "Default";
}
public void SetContainer(T container)
{
this.Container = container;
}
public bool Rename(String newName)
{
bool res = Container.IsNameBusy(newName);
if (!res) this.Name = String.Copy(newName);
return !res;
}
}
Next. Create ContainerBase
ContainerBase should:
1) has IContainer interface.
2)has information about what it will contain:
... where U : IUnit<C>, new()
3)and .... has information about what itself is. This information we need to pass as parameter to SetContainer() method.
Code ContainerBase:
class ContainerBase<U, C> : IContainer //U - Unit Class. C-Container Class
where U : IUnit<C>, new()
where C : ContainerBase<U, C>
{
protected List<U> Units;
public U this[int index] { get { return Units[index]; } }
public ContainerBase()//ctor
{
this.Units = new List<U>();
}
public void Add()
{
this.Units.Add(new U());
this.Units.Last().SetContainer(((C)this));//may be a bit strange but actualy this will have the same type as <C>
}
public bool IsNameBusy(String newName)
{
bool res = false;
foreach (var unt in this.Units)
{
if (unt.Name == newName)
{
res = true;
break;
}
}
return res;
}
public int Count { get { return this.Units.Count; } }
}
Cast ((TContainer)(this)) may be is a bit strange. But using ContainerBase we always should use NewInheritorContainer. So this cast is just do nothing…looks like...
Finally. This classes can be used like in this example.
class SheetContainer : ContainerBase<SheetUnit,SheetContainer> {public SheetContainer(){}}
class SheetUnit : UnitBase<SheetContainer>
{
public CellContainer Cells;
public PictureContainer Pictures;
public SheetUnit()
{
this.Cells = new CellContainer();
this.Pictures = new PictureContainer();
}
}
class CellContainer : ContainerBase<CellUnit, CellContainer> { public CellContainer() { } }
class CellUnit : UnitBase<CellContainer>
{
public string ValuePr;//Private Field
private const string ValuePrDefault = "Default";
public string Value//Property for Value
{
//All below are Just For Example.
get
{
return this.ValuePr;
}
set
{
if (String.IsNullOrEmpty(value))
{
this.ValuePr = ValuePrDefault;
}
else
{
this.ValuePr = String.Copy(value);
}
}
}
public CellUnit()
{
this.ValuePr = ValuePrDefault;
}
}
class PictureContainer : ContainerBase<PictureUnit, PictureContainer> { public PictureContainer() { } }
class PictureUnit : UnitBase<PictureContainer>
{
public int[,] Pixels{get;private set;}
public PictureUnit()
{
this.Pixels=new int[,]{{10,20,30},{11,12,13}};
}
public int GetSizeX()
{
return this.Pixels.GetLength(1);
}
public int GetSizeY()
{
return this.Pixels.GetLength(0);
}
public bool LoadFromFile(string path)
{
return false;
}
}
static void Main(string[] args)
{
SheetContainer Sheets = new SheetContainer();
Sheets.Add();
Sheets.Add();
Sheets.Add();
Sheets[0].Pictures.Add();
Sheets[1].Cells.Add();
Sheets[2].Pictures.Add();
Sheets[2].Cells.Add();
Sheets[2].Cells[0].Value = "FirstTest";
bool res= Sheets[0].Rename("First");//res=true
res=Sheets[2].Rename("First");//res =false
int res2 = Sheets.Count;
res2 = Sheets[2].Pictures[0].Pixels[1, 2];//13
res2 = Sheets[2].Pictures.Count;//1
res2 = Sheets[1].Pictures.Count;//0
res2 = Sheets[0].Pictures[0].GetSizeX();//3
Console.ReadKey();
}
Looks like it works like I want. But I didn’t test it full.
Let me say Thank you again, InBetween.

Handling objects of different classes in a derived List<T> class

I have several classes (A, B, C, ...) that all use a List<AnotherClass> to store references to 'other' objects. But 'other' is different for each of the classes A, B, C.
So
Class A contains List<Class_X>
Class B contains List<Class_Y>
Class C contains List<Class_Z>
Instead of implementing Add / Delete / Search (etc) functions in A, B, C it seems logical to me to create a class ListRef<T> from List<T>
public class ListRef<T>: List<T>
{
protected ListRef<T> ListOfObjects = null;
protected string name = null;
public ListRef<T>
{
ListOfObjects = new ListRef<T>();
}
}
Using the code above (is this the right code for what I want?) I don't know how I can supply the right class (Class_X, Class_Y, Class_Z) replacing/specifying <T> in the constructor of each class (A, B, C) that will use ListRef.
In the constructor of class A I would like to write something like:
public A() : base<Class_X>
{
}
How can I specify from WITHIN class A what kind of objects need to be stored in ListOfObjects?
I prefer NOT to write
public A()
{
ListOfObjects = new ListRef<Class_X();
}
as I would like to have ListOfObjects declared private instead of protected
Inside Listref I JUST want to be able to Add, Delete, Search objects. So I'm not actually using those classes (Class_X, Class_Y, Class_Z).
currently I have
public class A
{
private List<Class_X> ListOfObjects = null;
A()
{
ListOfObjects = new List<Class_X>();
}
public void Add(string Name)
{
Class_X Object = new Class_X(Name);
ListOfObjects.Add(Object);
}
public void Delete(Class_X Object)
{
ListOfObjects.Remove(Object);
}
}
and the same kind of code for class B (using Class_Y) and for class C (using class_Z).
To me it seems logical to use ONE class ListRef to perform the Add and Delete operations and maintain the list for all classes I use.
(of course the real code is more complicated)
If I understand you question correctly, it sounds like what you want to do is create a group of classes A, B, C, etc.. that each manage a collection of some other type (X, Y, Z) - but you don't want to duplicate some of the list management logic across A, B, and C.
There are two different ways to achieve this.
First, the inheritance approach: you could give A, B, and C a common generic base class that is parameterized on the type of the item each will manage. Here's a code example:
public abstract class ABCBase<T>
{
protected IList<T> m_List = new List<T>();
// methods that manage the collection
// I chose to make the virtual so that derived
// classes could alter then behavior - may not be needed
public virtual void Add( T item ) { ... }
public virtual void Remove( T item ) { ... }
public virtual int Find( T item ) { ... }
}
public class A : ABCBase<X> { ... }
public class B : ABCBase<Y> { ... }
public class C : ABCBase<Z> { ... }
Second, is the composition approach: create a manager class for your colleciton that implements the operations on the child list, and aggregate that in each of A, B, and C:
public class ListManager<T>
{
private IList<T> m_List = new List<T>();
public void Add( T item ) { ... }
public void Remove( T item ) { ... }
public int Find( T item ) { ... }
}
public class A
{
public ListManager<X> ListOfX { get; protected set; }
public A() { ListOfX = new ListManager<X>(); }
}
public class B
{
public ListManager<Y> ListOfX { get; protected set; }
public B() { ListOfY = new ListManager<Y>(); }
}
public class C
{
public ListManager<Z> ListOfX { get; protected set; }
public C() { ListOfX = new ListManager<Z>(); }
}
You could also choose to mix both of these approaches - creating a list management class but also creating base class (or interface) for A, B, C - so that each exposes a consistent property ChildList (or some such) that consumers could use without always having to know the type actual types A, B, C.
Here is how I would recommend doing it...
public class ABC_Base<TChild>
{
public IEnumberable<TChild> Children { get; set; }
public void AddChild(TChild item)
{
}
public void RemoveChild(TChild item)
{
}
//etc
}
public class A : ABC_Base<X> // X is the type for your child
{
}
//Used like so...
A myA = new A();
myA.AddChild(new X());
// or if you are wanting to specify when created then this...
public class A<TChild> : ABC_Base<TChild>
{
}
//Used like so...
A myA = new A<X>();
A myOtherA = new A<Y>();
myA.Addchild(new X());
myOtherA.AddChild(new Y());
How about
public interface ISomeOtherClass
{
}
public class Class_X : ISomeOtherClass
{
}
public class Class_Y : ISomeOtherClass
{
}
public class BaseClass<T> where T : ISomeOtherClass
{
public ListRef<T> OtherObjects { get; set; }
}
public class A : BaseClass<Class_x>
{
}
public class B : BaseClass<Class_Y>
{
}
I hope I am correctly understanding your problem. Here is how I would do it:
interface ILetter<T>
{
IList<T> OtherObjects { get; }
}
class A : ILetter<Class_X>
{
public IList<Class_X> OtherObjects
{
get { /* ... */ }
}
}
class B : ILetter<Class_Y>
{
public IList<Class_X> OtherObjects
{
get { /* ... */ }
}
}
// etc...
With this interface you can be sure that each type has a public IList<T> property that you can use for any operations you wish.

Categories