nested classes and interfaces - c#

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

Related

Pattern to avoid the need for Downcasting/Reflection

Suppose I have two implementations of a base class:
public class Base {
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base {
public void DoAThing() {...};
}
public class B : Base {
public void DoBThing(int anInteger) {...};
}
Suppose I want to put many instances of Base in a list, so that I can loop over them and call Stringify() on each, and make use of their shared functionality.
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> {thing1, thing2, thing3};
foreach(Base base in list) { Console.WriteLine(base.Stringify()); }
}
Now suppose there are many many Base objects, such that maintaining the individual thing references to each one is not realistic. Would there be any way, via only the list, to regain the DoAThing() or DoBThing() functionality that is lost by the abstraction without having to use explicit downcasting and reflection?
This feels like it would be a common enough occurance, so I am wondering if there is a design flaw or established pattern I am missing here that would help in this situation.
If you debug, you can notice every object of the list mantains its' class.
This way:
class Program
{
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> { thing1, thing2, thing3 };
foreach (Base bas in list) {
Console.WriteLine(bas.Stringify());
if(bas is A)
{
((A)bas).DoAThing();
}
else if (bas is B)
{
((B)bas).DoBThing(1);
}
else
{
//IDK
}
}
}
}
public abstract class Base
{
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base
{
public void DoAThing()
{
}
}
public class B : Base
{
public void DoBThing(int anInteger)
{
}
}

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

Array of inherited from generic types

Code to demonstrate the problem:
static void Main(string[] args)
{
var a = new A();
var b = new B();
Base<>[] all = new Base<>[] { a, b }; // doesn't work
}
class Base<T>
{
public string Caption { get { return typeof(T).ToString(); } }
}
class A : Base<A> { }
class B : Base<B> { }
Perhaps I went the wrong direction. Idea was to move Caption into base class (Base become generic). Non-generic version works without problems:
var all = new Base[] { a, b }; // no problems for as long as Base is not generic
There's no Type<?> in C# - you always have to specify a concrete generic type.
The only way around this is to make Base<T> inherit a non-generic base-class, or implement a non-generic interface. You could then use that as the type of the array.
EDIT:
In your case this is extremely simple, since the part of the interface you want doesn't include the generic type argument. So you can simply do either:
public abstract class Superbase
{
public abstract string Caption { get; }
}
public class Base<T>: Superbase
{
public override string Caption { get { return typeof(T).Name; } }
}
Or, using an interface:
public interface IBase
{
string Caption { get; }
}
public class Base<T>: IBase
{
public string Caption { get { return typeof(T).Name; } }
}
Your array would then be Superbase[] or IBase[], respectivelly. In both cases, you can see that I'm not actually providing an implementation - both the declarations are "abstract", in a sense.
In general, I'm trying to keep the non-generic stuff in a non-generic base class, rather than stuffing it in the derived generic classes. It just feels more clean :)
based on #Luaan ideea, here is an implementation:
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
var arr = new Base[] { a, b};
foreach (var obj in arr)
Console.WriteLine(obj.Caption);
Console.ReadKey();
}
}
public class Base<T> : Base
{
public override string Caption
{
get { return typeof (T).ToString(); }
}
}
public class A : Base<A> { }
public class B : Base<B> { }
public abstract class Base
{
public abstract string Caption { get; }
}
Instead of trying to use inheritance (which will lead to more problems down the line), use an extension method instead:
public interface IClassAORClassB {}
class A : IClassAORClassB { }
class B : IClassAORClassB { }
public static class Captions
{
public static string Caption<T>(this T obj) where T : IClassAORClassB
{
return obj.GetType().ToString();
}
}
static void Main(string[] args)
{
var a = new A();
var b = new B();
var all = new IClassAORClassB[] { a, b }; // works just fine
Console.WriteLine(all[0].Caption()); // prints A
Console.WriteLine(all[1].Caption()); // prints B
}

Controlling read/write access to fields

Suppose that we would like to separate out the read and write access in an interface pattern as below.
namespace accesspattern
{
namespace ReadOnly
{
public interface IA { double get_a(); }
}
namespace Writable
{
public interface IA : ReadOnly.IA { void set_a(double value); }
}
}
This is easy to implement:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
}
}
Suppose that we need another class which inherits from A and so we go ahead and define an interface for it:
namespace accesspattern
{
namespace ReadOnly
{
public interface IB : ReadOnly.IA { int get_b(); }
}
namespace Writable
{
public interface IB : ReadOnly.IB, Writable.IA { void set_b(int value); }
}
}
Implementing this is not so easy. One always feels that Writable.B should inherit from two base classes, Writable.A and ReadOnly.B, to avoid repeated code.
Is there a recommended Design Pattern to use? The aim is to be able to return "read access only" and "read write access" objects separately (decided at compile time) depending on requirements. It would be nice if the solution pattern makes it easy to add more layers of inheritance, classes C, D...
I know that the issue of Multiple Inheritance crops up here and that it has been discussed at length elsewhere in many, many, places. But my question is not so much "How to implement the interfaces which are defined inside the namespace accesspattern without using multiple inheritance" (although I would like to learn the best way to do that) but rather, how can we define the ReadOnly/Writable versions of a class separately and also support inheritance without it getting very, very, messy?
For what it is worth here is one (messy) solution [see below for much a better implementation]:
namespace accesspattern
{
namespace ReadOnly
{
public class A : IA
{
protected double a;
public double get_a() { return a; }
}
public class B : IB
{
protected int b;
public int get_b() { return b; }
}
}
namespace Writable
{
public class A : ReadOnly.A, IA
{
public void set_a(double value) { base.a = value; }
}
public class B : ReadOnly.B, IB
{
private IA aObj;
public double get_a() { return aObj.get_a(); }
public void set_a(double value) { aObj.set_a(value); }
public void set_b(int value) { base.b = value; }
public B() { aObj = new A(); }
}
}
}
}
Update: I think that this (below) is what Eugene is talking about. This implementation pattern is pretty good, I think. By only passing around "writeProtected" views of classes one can implement algorithms which require that the state of the class will not change and only use "writeEnabled" views where it is meant that the function will/could cause a change in state avoiding.
namespace access
{
// usual usage is at least readable
public interface IA { double get_a(); }
public interface IB : IA { int get_b(); }
// special usage is writable as well
namespace writable
{
public interface IA : access.IA { void set_a(double value); }
public interface IB : access.IB, IA { void set_b(int value);}
}
// Implement the whole of A in one place
public class A : writable.IA
{
private double a;
public double get_a() { return a; }
public void set_a(double value) { a = value; }
public A() { }
//support write-protection
public static IA writeProtected() { return new A(); }
public static writable.IA writable() { return new A(); }
}
// implement the whole of B in one place and now no issue with using A as a base class
public class B : A, writable.IB
{
private int b;
public double get_b() { return b; }
public void set_b(int value) { b = value; }
public B() : base() { }
// support write protection
public static IB writeProtected() { return new B(); }
public static writable.IB writable() { return new B(); }
}
public static class Test
{
static void doSomething(IA a)
{
// a is read-only
}
static void alterState(writable.IB b)
{
// b is writable
}
static void example()
{
// Write protected
IA a = access.A.writeProtected();
IB b = access.B.writeProtected();
// write enabled
writable.IA A = access.A.writable();
writable.IB B = access.B.writable();
Console.WriteLine(a.get_a());
B.set_b(68);
doSomething(A); // passed as writeprotected
alterState(B); // passed as writable
}
}
}
I know this thread is one year old, but I'm wondering if it would make sense to have something like this:
interface ReadOnlyA
{
object A { get; }
}
interface WriteableA : ReadOnlyA
{
new object A {get; set;}
}
You can provide the read/write access at Service level and not at Entity level. In that case you can code generate a wrapper around services that handles the read/write access.
Patterns used: Decorator, Dependency Injection

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