How can I limit class usage? - c#

I have a list of List<object>. How can I limit that only Class1 and Class2 should be used there is list?
Class1 and Class2 are basically different. I would guess what there is basic class for both this classes and restrict List to only work with it, but really don't know.

Make an interface that both classes implement
public interface MyInterface
{
}
public class Class1 : MyInterface
{
}
public class Class2 : MyInterface
{
}
List<MyInterface> myList = new List<MyInterface>();
The only instances of classes that can be referenced in the list are those that implement the MyInterface interface. In this case only Class1 and Class2.

I'm convinced that Bazz's answer is the correct way to handle such requirement.
There's however, another approach, that you can try :
public class MyCustomList : ArrayList
{
public override void Add(object item){
if(item is Class1 || item is Class2) {
base.Add(item);
}
else {
throw BadaboomException();
}
}
}
Or you can ensure signatures by wrapping the collection completely
public class MyCustomList : ICollection
{
private readonly ArrayList m_InnerList = new ArrayList();
public virtual void Add(Class1 item) {
this.m_InnerList.Add(item);
}
public virtual void Add(Class2 item) {
this.m_InnerList.Add(item);
}
public void CopyTo(Array array, int index) {
m_InnerList.CopyTo(array, index);
}
public int Count { get { return m_InnerList.Count; } }
public bool IsSynchronized { get{ return m_InnerList.IsSynchronized; } }
public object SyncRoot { get{ return m_InnerList.SyncRoot; } }
public IEnumerator GetEnumerator(){
return m_InnerList.GetEnumerator();
}
}

Related

How to make manual alternative to List<> class

I need to make alternative to List<> class where I will have 4 methods... Two for adding int items, one from front, other from behind and two for deleting, one from front and other from behind as well. My class should not inherit anything.
Something like this...
public class MyList
{
public void AddItemsFront(int pItem)
{
}
public void AddItemsBehind(int pItem)
{
}
public void DeleteItemsFront(int pItem)
{
}
public void DeleteItemsBehind(int pItem)
{
}
}
You could hold an instance of a List<T> in a field, List<T> has already these methods:
public class MyList<T>
{
private List<T> _TheList;
public MyList()
{
_TheList = new List<T>();
}
public List<T> TheList { get { return _TheList; } set { _TheList = value; } }
public void AddItemFront(T pItem)
{
TheList.Insert(0, pItem);
}
public void AddItemBehind(T pItem)
{
TheList.Add(pItem);
}
public void DeleteItemFront()
{
TheList.RemoveAt(0);
}
public void DeleteItemBehind()
{
TheList.RemoveAt(TheList.Count - 1);
}
}
Since it's a generic class you could also use it for different types than int.
var myList = new MyList<int>();
myList.AddItemFront(1);
Create a class that's got a data member of the correct List<> type, and implement your methods by calling the appropriate methods on the List<> data member. You will want your delete operations to return the object they removed from the list.
This is often referred to as the Adapter pattern. Wikipedia has a page on it.

How to benefit from type-overloading when iterating without downcasting?

I've found some code that is a bit long in a method:
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
if (item is Son) {
...SOME CODE...
}
else if (item is Daughter) {
...MORE CODE...
}
}
}
}
Because of this big if-else block, the method is quite large, and smells as bad design (OOP-wise).
I've tried to come up with something a bit more polymorphic, taking advantage of method-overloading via different type-paramaters, such as:
class MainClass
{
private static void DoSomething (Son son)
{
Console.WriteLine ("Son");
}
private static void DoSomething (Daughter daughter)
{
Console.WriteLine ("Daughter");
}
private static void DoSomething (Parent parent)
{
Console.WriteLine ("Parent");
}
private void Iterate(IEnumerable<Parent> list)
{
foreach (var item in list) {
DoSomething (item);
}
}
}
But this doesn't work because it always prints "Parent", so I guess I would need to downcast manually, which defeats the point a bit, and would not look elegant.
One last point: if you are tempted to recommend me to put the implementation of DoSomething in the derived classes of Parent, that is not possible, because of dependency problems (the assembly where these 3 classes live cannot have dependencies on some things that the SOME CODE and MORE CODE is calling).
So what would be the best approach to refactor this? Thanks!
There are several ways to do this asides from the switch statement you've already identified (which definitely gets clunky with more than a couple of types involved).
First of all, if you aren't likely to add subtypes, but you are likely to add other things to do with the subtypes, you can use the Visitor Pattern to mimic double dispatch.
class Parent
{
public abstract void Accept(IChildVisitor visitor);
}
class Son : Parent
{
public override void Accept(IChildVisitor visitor)
{
visitor.Visit(this);
}
}
class Daughter : Parent
{
public override void Accept(IChildVisitor visitor)
{
visitor.Visit(this);
}
}
interface IChildVisitor
{
Visit(Son son);
Visit(Daughter daughter);
}
class SomeCodeChildVisitor : IChildVisitor
{
public Visit(Son son)
{
...SOME CODE...
}
public Visit(Daughter daughter)
{
...SOME CODE...
}
}
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
item.Accept(new SomeCodeChildVisitor());
}
}
}
You can also use a Dictionary<Type,Action>
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
// If you don't actually need a reference to the child
private void IDictionary<Type, Action> map =
new Dictionary<Type, Action>()
{
{ typeof(Son), () => ...SOME CODE... }
{ typeof(Daughter), () => ...SOME CODE... }
};
// If you do need a reference to the child
private void IDictionary<Type, Action<Parent>> otherMap =
new Dictionary<Type, Action<Parent>>()
{
{ typeof(Son), x => (Son)x. ...SOME CODE... }
{ typeof(Daughter), y => (Daughter)x. ...SOME CODE... }
};
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
// either
map[item.GetType()]();
// or
otherMap[item.GetType()](item);
}
}
}
You can also use the dynamic keyword
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Parent item in list) {
Visit((dynamic)item);
}
}
private void Visit(Son son)
{
...SOME CODE...
}
private void Visit(Daughter daughter)
{
...SOME CODE...
}
}
You can also just filter the types straight out of your collection with Linq (especially if you only care about some subtypes and not others, e.g. if you're iterating through a Controls collection and you only care about Buttons)
class Parent { }
class Son : Parent { }
class Daughter : Parent { }
class MainClass
{
private void Iterate(IEnumerable<Parent> list)
{
foreach (Daughter daughter in list.OfType<Daughter>()) {
...SOME CODE...
}
}
}
In C# I generally recommend the dictionary approach, but any will do in a pinch.
The best situation is to move DoSomething() method to the classes. If not possible, maybe you still can use conditionals to polymorphism, but with the decorator pattern. In this case you can
Define an abstract class with an abstract method DoSomething(). Let's call it FamilyDecorator. It's a good idea to create a constructor which receives a Parent in his parameter, so you can save it as a protected variable (that means: visible to all of the derived classes).
Declare one decorator for each class on your assembly: ParentDecorator, SonDecorator, DaughterDecorator. These three classes inherit from FamilyDecorator and must override the DoSomething() method.
The trick is to create a method in the abstract class that returns one or another Decorator, based on type. That's the way you can separate which logic use on each case:
abstract class FamilyDecorator
{
protected Domain.Parent _member;
public abstract void DoSomething();
internal FamilyDecorator(Domain.Parent member)
{
_member = member;
}
public static FamilyDecorator GetDecorator(Domain.Parent item)
{
if(item.GetType() == typeof(Domain.Parent))
{
return new ParentDecorator(item);
}
else if (item.GetType() == typeof(Domain.Son))
{
return new SonDecorator(item);
}
else if (item.GetType() == typeof(Domain.Daughter))
{
return new DaughterDecorator(item);
}
return null;
}
}
class ParentDecorator : FamilyDecorator
{
internal ParentDecorator(Domain.Parent parent)
: base(parent)
{
}
public override void DoSomething()
{
Console.WriteLine("A parent");
}
}
class SonDecorator : FamilyDecorator
{
internal SonDecorator(Domain.Parent son)
: base(son)
{
this._member = son;
}
public override void DoSomething()
{
Console.WriteLine("A son");
}
}
class DaughterDecorator : FamilyDecorator
{
internal DaughterDecorator(Domain.Parent daughter)
: base(daughter)
{
}
public override void DoSomething()
{
Console.WriteLine("A daughter");
}
}
Then, in your Main class:
foreach (Parent item in list)
{
var decorator = FamilyDecorator.GetDecorator(item);
decorator.DoSomething();
}
This solution keeps the code very clean and takes advantage of polymorphism.
Edit
I don't think I like this solution because you're basically moving the
type checking from the foreach loop to the GetDecorator() method.
Polymorphism should allow you to do this without type checking
manually.
There is another solution, based on the same idea: to use reflection for the object construction.
In this case:
Instead of an abstract class you define an Interface that declares the DoSomething() method.
Now each decorator inherits from their corresponding class (Parent - ParentDecorator, Son - SonDecorator, etc.)
You need to change the constructors in the Decorator classes. They need to be public if you want to use reflection.
Finally, the GetDecorator() method just search for the derived class in the assembly. If found, it returns the decorator.
namespace FamilyNamespace
{
interface IFamily
{
void DoSomething();
}
class ParentDecorator : Domain.Parent, IFamily
{
private Domain.Parent _member;
public ParentDecorator(Domain.Parent parent)
{
this._member = parent;
}
public void DoSomething()
{
Console.WriteLine("A parent");
}
}
class SonDecorator : Domain.Son, IFamily
{
private Domain.Parent _member;
public SonDecorator(Domain.Parent son)
{
this._member = son;
}
public void DoSomething()
{
Console.WriteLine("A son");
}
}
class DaughterDecorator : Domain.Daughter, IFamily
{
private Domain.Parent _member;
public DaughterDecorator(Domain.Parent daughter)
{
this._member = daughter;
}
public void DoSomething()
{
Console.WriteLine("A daughter");
}
}
}
Then in your Main class:
static FamilyNamespace.IFamily GetDecorator(Domain.Parent item)
{
var baseType = item.GetType();
var derivedType = Assembly.GetExecutingAssembly().GetTypes().Where(m => m != baseType && baseType.IsAssignableFrom(m));
if (derivedType.Any())
{
return (FamilyNamespace.IFamily)Activator.CreateInstance(derivedType.First(), new object[] { item });
}
return null;
}
... and the Main method:
foreach (Domain.Parent item in list)
{
var decorator = (FamilyNamespace.IFamily)GetDecorator(item);
decorator.DoSomething();
}
Greetings

c# return this for generic return type method

Many of the methods inside my class would return this; so that i can call multiple functions within one line. something like a.method1().method2().method3(); problem arise when i try to make a base class. if I make a method to return type T inside the base class, then i can no longer return this; since the base class type is not T. I can't just make the return type as the base class since there are many more methods that are available on the inherited class that are not in the base class. How can i solve this problem?
Sample code:
public class baseClass<T>
{
public T method1()
{
//Do stuffs
return this;//doesnt work
}
}
public class inheritedClass:baseClass<inheritedClass>
{
public inheritedClass method2()
{
//Do stuffs
return this;
}
}
May be this
public abstract class BaseClass<T> where T : BaseClass<T>
{
public T Method1()
{
//Do stuffs
// We are sure any instance of this class is T : BaseClass<T>.
// Only exception might be direct instance of BaseClass<T> and that's why we made BaseClass abstract.
return (T)this;
}
}
public class InheritedClass : BaseClass<InheritedClass>
{
public InheritedClass Method2()
{
//Do stuffs
return this;
}
}
Two things changed. First, we are still casting but doing that in base class. Second we guaranteed this cast to work with where constraint and abstract.
Your base class's return type should be the base class itself, not just T.
public class baseClass<T>
{
public baseClass<T> method1()
{
//Do stuffs
return this;
}
}
In your base class example, "this" is not a type of "T" but is instead a type of "baseClass{T}". That's why it doesn't work. I'm not sure what you're trying to accomplish here, but this would probably compile...
public class baseClass<T>
{
public baseClass<T> method1()
{
return this;
}
}
public class inheritedClass : baseClass<inheritedClass>
{
public baseClass<inheritedClass> method2()
{
return this.method1();
}
}
Edit: I understand your question now. This is probably a better overall approach than using inheritance. You can convert the interface to be a generic one if needed...
public interface FluentStuff
{
FluentStuff method1();
FluentStuff method2();
}
public class MyClass : FluentStuff
{
public FluentStuff method1()
{
return this;
}
public FluentStuff method2()
{
return this;
}
}
But if you insist on using inheritance...
public interface FluentStuff
{
FluentStuff method1();
FluentStuff method2();
}
public abstract class BaseClass : FluentStuff
{
public virtual FluentStuff method1()
{
return this;
}
public abstract FluentStuff method2();
}
public class MyClass : BaseClass, FluentStuff
{
public override FluentStuff method2()
{
return this;
}
}
I highly encourage composition over inheritance.
Example with generics...
public interface FluentStuff<T>
{
FluentStuff<T> method1();
FluentStuff<T> method2();
}
public abstract class BaseClass<T> : FluentStuff<T>
{
public virtual FluentStuff<T> method1()
{
return this;
}
public abstract FluentStuff<T> method2();
}
public class MyClass : BaseClass<MyClass>, FluentStuff<MyClass>
{
public override FluentStuff<MyClass> method2()
{
return this;
}
}
Final example to another question/concern you posted...
public class SharedFunctionality
{
public void DoStuff1()
{
// common implementation for do stuff 1
}
public void DoStuff2()
{
// common implementation for do stuff 2
}
}
public class MyClass1
{
private readonly SharedFunctionality sharedFunctionality;
public MyClass1()
{
this.sharedFunctionality = new SharedFunctionality();
}
public MyClass1 Method1()
{
this.sharedFunctionality.DoStuff1();
return this;
}
public MyClass1 Method2()
{
this.sharedFunctionality.DoStuff2();
return this;
}
}
public class MyClass2
{
private readonly SharedFunctionality sharedFunctionality;
public MyClass2()
{
this.sharedFunctionality = new SharedFunctionality();
}
public MyClass2 Method1()
{
this.sharedFunctionality.DoStuff1();
return this;
}
public MyClass2 Method2()
{
this.sharedFunctionality.DoStuff2();
return this;
}
public MyClass2 Method3()
{
// do something only this class does
return this;
}
}
class Program
{
static void Main(string[] args)
{
MyClass1 c1 = new MyClass1();
c1.Method1().Method2();
MyClass2 c2 = new MyClass2();
c2.Method1().Method2().Method3();
}
}

Derived types with Method overloading

The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?

Cannot add object to list

I'm trying out an example of using Domain Events to notify of when something has happened in a system (borrowed from here and here).
I'm really close to getting the code working how I want, however, I've hit a bit of a brick wall. Here is my DomainEvents class:
public static class DomainEvents
{
[ThreadStatic]
private static IList<IEventHandler<IDomainEvent>> Actions;
public static void Register<T>(IEventHandler<T> callback) where T : IDomainEvent
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback); // <---- Problem here, since I can't add callback to the collection.
}
public static void ClearCallbacks()
{
Actions = null;
}
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Actions == null)
{
return;
}
foreach (var action in Actions)
{
if (action is IEventHandler<T>)
{
((IEventHandler<T>)action).Handle(args);
}
}
}
The above won't compile because Actions.Add cannot accept callback since it's a IEventHandler<T> type rather then a IEventHandler<IDomainEvent> type. Here's some more code to clarify.
This is called from my console application:
DomainEvents.Register(new CustomerHasUnpaidDuesEventHandler());
CustomerHasUnpaidDuesEventHandler implements IEventHandler<CustomerHasUnpaidDuesEvent>, where CustomerHasUnpaidDuesEvent implements IDomainEvent.
public class CustomerHasUnpaidDuesEventHandler : IEventHandler<CustomerHasUnpaidDuesEvent>
{
public IEmailSender EmailSender { get; set; }
public void Handle(CustomerHasUnpaidDuesEvent #event)
{
this.EmailSender.SendEmail(#event.Customer.EmailAddress);
}
}
public class CustomerHasUnpaidDuesEvent : IDomainEvent
{
public CustomerHasUnpaidDuesEvent(Customer customer)
{
this.Customer = customer;
}
public Customer Customer { get; set; }
}
This is what I don't get - if CustomerHasUnpaidDuesEvent implements IDomainEvent, then why is the call to Actions.Add failing? How can I resolve this?
EDIT:
To make things clearer, here is entire code for my test app:
class Program
{
static void Main()
{
DomainEvents.Register(new CustomerHasUnpaidDuesEventHandler());
var c = new Customer();
c.EmailAddress = "test#dfsdf.com";
c.CheckUnpaidDues();
}
}
public interface IEventHandler<in T> where T : IDomainEvent
{
void Handle(T args);
}
public interface IEmailSender
{
void SendEmail(string emailAddress);
}
public interface IDomainEvent
{
}
public static class DomainEvents
{
[ThreadStatic]
private static IList<IEventHandler<IDomainEvent>> Actions;
public static void Register<T>(IEventHandler<T> callback) where T: IDomainEvent
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback);
}
public static void ClearCallbacks()
{
Actions = null;
}
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Actions == null)
{
return;
}
foreach (IEventHandler<T> action in Actions)
{
(action).Handle(args);
}
}
}
public class CustomerHasUnpaidDuesEventHandler : IEventHandler<CustomerHasUnpaidDuesEvent>
{
public IEmailSender EmailSender { get; set; }
public void Handle(CustomerHasUnpaidDuesEvent #event)
{
this.EmailSender.SendEmail(#event.Customer.EmailAddress);
}
}
public class CustomerHasUnpaidDuesEvent : IDomainEvent
{
public CustomerHasUnpaidDuesEvent(Customer customer)
{
this.Customer = customer;
}
public Customer Customer { get; set; }
}
public class Customer
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public bool HasUnpaidDues { get; set; }
public void CheckUnpaidDues()
{
HasUnpaidDues = true;
DomainEvents.Raise(new CustomerHasUnpaidDuesEvent(this));
}
}
Cheers.
Jas.
There is no need for your Register method to be generic:
public static void Register(IEventHandler<IDomainEvent> callback)
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback);
}
Edit:
The problem is that in order to have IEventHandler<CustomerHasUnpaidDuesEvent> to be in the list of IEventHandler<IDomainEvent>s, we need T to be a covariant template parameter in IEventHandler<T> (which is declared as IEventHandler<out T>). However in order to allow the function Handle(T arg), we need T to be contravariant. So strictly this way won't work. Imagine: if we really could insert an IEventHandler<CustomerHasUnpaidDuesEvent> into a list of IEventHandler<IDomainEvent>s, than someone might try to call Handle with the argument of some type which derives from IDomainEvent but is not a CustomerHasUnpaidDuesEvent! This should be impossible to do.
The solution is that we don't need the exact type at Register, so we can keep a reference to a generic base interface. The implementation is here: http://ideone.com/9glmQ
Old answer is not valid, kept below for consistency.
Maybe you need to declare IEventHandler to accept T as a covariant type?
interface IEventHandler<in T> where T: IDomainEvent
{
void Handle();
// ...
}
Edit: surely CustomerHasUnpaidDuesEvent is an IDomainEvent, but you need IEventHandler<CustomerHasUnpaidDuesEvent> to be a IEventHandler<IDomainEvent>. This is exactly what covariance does. In order to allow that, your template parameter in IEventhandler must be declared covariant (<in T> instead of just <T>).

Categories

Resources