I'm new to C# and wondered if there is something like private inheritance in C# (like in C++) ?
My problem is as follows:
I want to implement a queue (name it SpecialQueue) with the following changes:
The queue has a maximum number of items that can be stored in it.
If the queue is full and you insert a new item, one item will be automatically poped out of the queue (the first item in the queue) and the new item will be inserted to the end of the queue.
Some methods (such as peek()) provided by queue should not be exposed to SpecialQueue's users.
In c++ I would private ihnerit from queue, expose only the methods I want to and change others to my will. But unfortunatley, all methods in queue don't have the "Override" modifier and I don't know how to achieve that in C#.
Any help?
Regards,
Dan
Use composition: include a usual Queue as a field in your SpecialQueue. Private inheritance is actually something very similar to composition.
See http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 for discussion.
Implementation could be something like that:
public class SpecialQueue<T>
{
private int capacity;
private Queue<T> storage;
public SpecialQueue(int capacity)
{
this.capacity = capacity;
storage = new Queue<T>();
// if (capacity <= 0) throw something
}
public void Push(T value)
{
if (storage.Count == capacity)
storage.Dequeue();
storage.Enqueue(value);
}
public T Pop()
{
if (storage.Count == 0)
throw new SomeException("Queue is empty");
return storage.Dequeue();
}
public int Count
{
get { return storage.Count; }
}
}
You need to add more functions/interfaces if you want SpecialQueue to support them. I would however not recommend to implement IEnumerable, because this would allow Peek (which you want to prohibit).
You could implement the same interfaces as a Queue (or Queue<T>), have a Queue as a backing field and expose those methods that you need to, which will simply wrap the calls to the backing field.
For example (have kept implementation of ICollection in line with Queue<T>)
public class SpecialQueue<T> : IEnumerable<T>, ICollection
{
private readonly Queue<T> _queue;
#region Constructors
public SpecialQueue()
{
_queue = new Queue<T>();
}
public SpecialQueue(int capacity)
{
_queue = new Queue<T>(capacity);
}
public SpecialQueue(IEnumerable<T> collection)
{
_queue = new Queue<T>(collection);
}
#endregion
#region Methods
// implement any methods that you want public here...
#endregion
#region Interface Implementations
public IEnumerator<T> GetEnumerator()
{
return _queue.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _queue.GetEnumerator();
}
public void CopyTo(Array array, int index)
{
((ICollection) _queue).CopyTo(array, index);
}
public int Count
{
get { return _queue.Count; }
}
public object SyncRoot
{
get { return ((ICollection) _queue).SyncRoot; }
}
public bool IsSynchronized
{
get { return ((ICollection) _queue).IsSynchronized; }
}
#endregion
}
Related
I have class with two properties which are Lists, one of it contents int - that's IDs of objects from second List. I override setters and getters to save them agreeable with each other. But when I add some this to list they are not synchronized. How to make them synchronized?
Here is code
public class Item
{
private List<Operation> _operations = new List<Operation>();
private List<int> _operationsID = new List<int>();
public List<Operation> operations
{
get { return this._operations; }
set
{
this._operations = value;
if (value != null)
{
foreach (Operation oper in value)
{
this._operationsID.Add(oper.ID);
}
}
}
}
public List<int> operationsID
{
get { return this._operationsID; }
set
{
this._operationsID = value;
if (value != null)
{
foreach (int operID in value)
{
this._operations.Add(new Operation(operID));
}
}
}
}
}
Should I override List.Add if so, how it can me made?
It is a bit unclear what it is you are trying to do, but basically it seems like you need to encapsulate those lists so the user can't work on them directly (and get them out of sync). You do this by not exposing the lists to the user. Basically you are trying to keep the items contained to the user so whenever they work on your set of items, they would be forced to go through this class and the functions that class exposes. Your only issue then is to find out what to expose to the user and in what manner.
public class Item {
private List<Operation> _operations = new List<Operation>();
private List<int> _operationsID = new List<int>();
public void addOperation(Operation o) {
_operations.Add(o);
_operationsID.Add(getIdentifier(o));
}
public void removeOperation(Operation o) {
_operations.Remove(o);
_operationsID.Remove(getIdentifier(o));
}
public void clear() {
_operations.clear();
_operationsID.clear();
}
public void findOperationMatching(Foobar foo) {
//
}
private int getIdentifier(Operation id) {
//
}
}
You have to clear previous list content before calling Add method:
public List<Operation> operations
{
get { return this._operations; }
set
{
this._operations = value;
if (value != null)
{
this._operationsID.Clear();
foreach (Operation oper in value)
{
this._operationsID.Add(oper.ID);
}
}
else
{
this._operationsID = null;
}
}
}
But to be honest, I don't think it's a good idea to keep these things in two different lists. Why don't you use Dictionary<int, Operation>?
It's a bad idea to try to manage two versions of the truth. If it were me, I'd expose one List<Operation> that callers can Add/Remove, and a second IEnumerable<int> which simply exposes the ID's of the operations:
public List<Operation> Operations { get; set; }
public IEnumerable<int> OperationIDs
{
get
{
return Operations.Select(op => op.OperationID);
}
}
This way, callers can use the Operations list to do whatever they need to do (Add, Remove, Count, etc). The OperationIDs is now not a second property that people can work with; instead it only reflects information that is in the Operations property.
I've got a good old InvalidOperationException being thrown with the standard message
Collection was modified; enumeration operation may not execute.
The problem is, the enumerator isn't modifying itself, for example:
private TRoute _copyRoute(TRoute route)
{
TRoute tempRoute = new TRoute();
tempRoute.Initialize(route.Resource);
foreach (TVisit visit in route)
{
tempRoute.Add(visit);
}
tempRoute.EndLocation = route.EndLocation;
return tempRoute;
}
My code is multi-threaded (circa 12-15 threads for this example) and each thread is supposed to be working on its own deep clone of a route. Obviously something is going wrong somewhere, but, my question is how do I track this down with so many threads? Reducing the number significantly stops the problem manifesting itself.
In this case my route instance is an IList so I can play around with adding things to the interface. Underneath it has it's own List implementation.
EDIT
Just to add, I could ToArray() or ToList() this and maybe ignore the problem here but I don't really want to do that, I want to locate the cause. For example:
If I change it to the following:
private TRoute _copyRoute(TRoute route)
{
TRoute tempRoute = new TRoute();
tempRoute.Initialize(route.Resource);
foreach (TVisit visit in route.ToList())
{
tempRoute.Add(visit);
}
tempRoute.EndLocation = route.EndLocation;
return tempRoute;
}
Then I fail on this Assert, because a chance has occurred just before ToList()... I need to try and find out where that change is occuring
TRoute tempRoute1 = CopyRoute(route1);
TRoute tempRoute2 = CopyRoute(route2);
Debug.Assert(tempRoute1.Count == route1.Count);
Here's something you can use to wrap your IList<T> - it checks that it's on the right thread on each write operation. Of course, it would still be unsafe to be iterating over this on one thread while writing on another, but I assume that's not the problem. (You could always call CheckThread on all operations, not just the writing ones.)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
class ThreadAffineList<T> : IList<T>
{
private readonly Thread expectedThread;
private readonly IList<T> list;
public ThreadAffineList(IList<T> list)
{
this.list = list;
this.expectedThread = Thread.CurrentThread;
}
private void CheckThread()
{
if (Thread.CurrentThread != expectedThread)
{
throw new InvalidOperationException("Incorrect thread");
}
}
// Modification methods: delegate after checking thread
public T this[int index]
{
get { return list[index]; }
set
{
CheckThread();
list[index] = value;
}
}
public void Add(T item)
{
CheckThread();
list.Add(item);
}
public void Clear()
{
CheckThread();
list.Clear();
}
public void Insert(int index, T item)
{
CheckThread();
list.Insert(index, item);
}
public bool Remove(T item)
{
CheckThread();
return list.Remove(item);
}
public void RemoveAt(int index)
{
CheckThread();
list.RemoveAt(index);
}
// Read-only members
public int Count { get { return list.Count; } }
public bool IsReadOnly { get { return list.IsReadOnly; } }
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T item)
{
return list.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array, arrayIndex);
}
public int IndexOf(T item)
{
return list.IndexOf(item);
}
}
Assuming you're in control of Add(TVisit)/Remove(TVisit) of TRoute underlying collection:
Extend your TRoute.IEnumerator<TVisit> GetEnumerator() to set an AutoResetEvent or Mutex
Extend your Add(TVisit)/Remove(TVisit) methods to wait for event/mutex with zero timeout
if(!autoReseEvent.WaitOne(0)) throw new MyException();
Catch MyExpcetion and you'll get the stack trace and change origin.
UPDATE:
The issue with this approach is when to release event/mutex. You'll probably have to decorate your enumerator with a new class like below:
public IEnumerator<TVisit> GetEnumerator()
{
IEnumerator<TVisit> originEnum = // get it somehow from underlying collection
IEnumerator<TVisit> evenlope = new DisposableEvenlope<TVisit>(originEnum);
evenlope.Disposed += new EventHandler(/* do your magic and reset event/mutex here */);
return evenlope;
}
And the evelope itself:
public class DisposableEvenlope<T> : IEnumerator<T>
{
private IEnumerator<T> _privateEnum;
public event System.EventHandler Disposed;
public DisposableEvenlope(IEnumerator<T> privateEnum)
{
_privateEnum = privateEnum;
}
public T Current
{
get { return _privateEnum.Current; }
}
public void Dispose()
{
Disposed(this, new System.EventArgs());
}
object IEnumerator.Current
{
get { return _privateEnum.Current; }
}
public bool MoveNext()
{
return _privateEnum.MoveNext();
}
public void Reset()
{
_privateEnum.Reset();
}
}
The problem is obviously not in the code you have written as you are not modifying the collection while enumerating.
Somehow one of two things is happening:
Your route is somehow not a deep clone and some thread is modyfying the same collection you are passing to the pasted logic (that should be easy to track is it is a coding issue somewhere, not some nasty race condition).
Your exception is being raised precisely in the cloning logic and not in the code you have pasted.
Try implementing some locking mechanism while deep cloning your collection and see if that solves the issue.
Since you are aware that mutiple thread can touch route, prevent any touch on route with a lock(), and always in a lock() convert route.ToArray() and then use that array for loop. This since you probably feel some performance drawbacks if you lock() the entire loop. To catch who is really touching the collection, you can derive it and track the thread id in a local member variable in the add/remove elements.
I have a class that takes an observable in its constructor, then subscribes to it and does some stuff, sets properties etc. The class itself is observable.
I want to subscribe to my source observable only if someone is subscribed to my class, but I can't figure out how to do it.
public MyClass : IObservable<MyResult>
{
private readonly Subject<MyResult> _subject = new Subject<MyResult>();
private readonly IConnectableObservable<MySource> _source;
public MyClass(IObservable<MySource> source)
{
_source = source
//All my logic to set properties and such
//goes here as a side effect, instead of in a subscription...
.Do(...)
//I hope that by publishing, side effects will happen only once...
.Publish();
}
public IDisposable Subscribe(IObserver<MyResult> observer)
{
return new CompositeDisposable(
_source.Subscribe(/*
don't have anything to do here,
just subscribing to make sure I'm subscribed to source...
(this can't be the right way to do it)
*/),
_subject.Subscribe(observer));
}
}
UPDATE
#Scott: I can see why implementing IObservable would be an anti-pattern. My Class needs to consume a single observable, and exposes 3 as properties (originally the most commonly used observable was going to be returned by MyClass itself, but I think that having it as a property might be better.
What I'm trying to write is an observable ICommand. I know some exist, but this is more of a way to learn Rx...
public class ObservableCommand<T> : ICommand
{
private readonly ISubject<T> _executeRequests = new Subject<T>();
private readonly ISubject<T> _canExecuteRequests = new Subject<T>();
public IObservable<bool> CanExecuteChanges { get; private set; }
public IObservable<T> CanExecuteRequests { get; private set; }
public IObservable<T> ExecuteRequests { get; private set; }
public ObservableCommand(IObservable<bool> canExecute)
{
var source = canExecute.DistinctUntilChanged()
//How do I dispose of subscription later?
//I have this fear that I'm going to have a chain of references,
//and my entire app will never get GC'd!
var subscription = source.Subscribe(
o => {
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
});
CanExecuteChanges = source;
CanExecuteRequests = _canExecuteRequests.AsObservable();
ExecuteRequests = _executeRequests.AsObservable();
}
#region ICommand Members
public bool CanExecute(object parameter)
{
_canExecuteRequests.OnNext(parameter is T ? (T)parameter : default(T));
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_executeRequests.OnNext(parameter is T ? (T)parameter : default(T));
}
#endregion
}
How about just not Doing or Publishing in the constructor, but rather in the Subscribe method?
It should be said, explicitly implementing IObservable<T> is something of an Rx anti-pattern.
You can make Subscriptions dependent on other subscribers with Defer and Create, something like
IObservable<MySource> source;
IObservable<MySource> sourceWithSubSideEffect = Observable.Defer(() =>
{
// Do something interesting on Subscription
// ....
return source;
});
I've prepared a snipped for you. MyClass implements IObservable<T> and has also methods of IObserver<T> but they are all private. With additional OnInitialize and OnSubscribe you should be able to do whatever you want on any event you want to response to.
If you want to make this snipped reusable you could define all methods as partial as they all return void. Then you could create definition to whatever you want.
public class MyClass<T> : IObservable<T>
{
private readonly IObservable<T> m_Source;
public MyClass(IObservable<T> source)
{
if (source == null) throw new ArgumentNullException("source");
m_Source = source.Do(OnNext, OnError, OnCompleted);
OnInitialize();
}
public IDisposable Subscribe(IObserver<T> observer)
{
OnSubscribe();
return m_Source.Subscribe(observer);
}
private void OnInitialize()
{
Console.WriteLine("OnInitialize");
}
private void OnSubscribe()
{
Console.WriteLine("OnSubscribe");
}
private void OnNext(T value)
{
Console.WriteLine("OnNext: {0}", value);
}
private void OnError(Exception error)
{
Console.WriteLine("OnError: {0}", error.Message);
}
private void OnCompleted()
{
Console.WriteLine("OnCompleted");
}
}
I'm writing a wrapper around a 3rd party library, and it has a method to scan the data it manages. The method takes a callback method that it calls for each item in the data that it finds.
e.g. The method is essentially: void Scan(Action<object> callback);
I want to wrap it and expose a method like IEnumerable<object> Scan();
Is this possible without resorting to a separate thread to do the actual scan and a buffer?
You can do this quite simply with Reactive:
class Program
{
static void Main(string[] args)
{
foreach (var x in CallBackToEnumerable<int>(Scan))
Console.WriteLine(x);
}
static IEnumerable<T> CallBackToEnumerable<T>(Action<Action<T>> functionReceivingCallback)
{
return Observable.Create<T>(o =>
{
// Schedule this onto another thread, otherwise it will block:
Scheduler.Later.Schedule(() =>
{
functionReceivingCallback(o.OnNext);
o.OnCompleted();
});
return () => { };
}).ToEnumerable();
}
public static void Scan(Action<int> act)
{
for (int i = 0; i < 100; i++)
{
// Delay to prove this is working asynchronously.
Thread.Sleep(100);
act(i);
}
}
}
Remember that this doesn't take care of things like cancellation, since the callback method doesn't really allow it. A proper solution would require work on the part of the external library.
You should investigate the Rx project — this allows an event source to be consumed as an IEnumerable.
I'm not sure if it allows vanilla callbacks to be presented as such (it's aimed at .NET events) but it would be worth a look as it should be possible to present a regular callback as an IObservable.
Here is a blocking enumerator (the Scan method needs to run in a separate thread)
public class MyEnumerator : IEnumerator<object>
{
private readonly Queue<object> _queue = new Queue<object>();
private ManualResetEvent _event = new ManualResetEvent(false);
public void Callback(object value)
{
lock (_queue)
{
_queue.Enqueue(value);
_event.Set();
}
}
public void Dispose()
{
}
public bool MoveNext()
{
_event.WaitOne();
lock (_queue)
{
Current = _queue.Dequeue();
if (_queue.Count == 0)
_event.Reset();
}
return true;
}
public void Reset()
{
_queue.Clear();
}
public object Current { get; private set; }
object IEnumerator.Current
{
get { return Current; }
}
}
static void Main(string[] args)
{
var enumerator = new MyEnumerator();
Scan(enumerator.Callback);
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
You could wrap it in a simple IEnumerable<Object>, but I would not recommend it. IEnumerable lists implies that you can run multiple enumerators on the same list, which you can't in this case.
How about this one:
IEnumerable<Object> Scan()
{
List<Object> objList = new List<Object>();
Action<Object> action = (obj) => { objList.Add(obj); };
Scan(action);
return objList;
}
Take a look at the yield keyword -- which will allow you to have a method that looks like an IEnumerable but which actually does processing for each return value.
This is kind of hard to explain, I hope my English is sufficient:
I have a class "A" which should maintain a list of objects of class "B" (like a private List). A consumer of class "A" should be able to add items to the list. After the items are added to the list, the consumer should not be able to modify them again, left alone that he should not be able to temper with the list itself (add or remove items). But he should be able to enumerate the items in the list and get their values. Is there a pattern for it? How would you do that?
If the question is not clear enough, please let me know.
To prevent editing the list or its items you have to make them immutable, which means you have to return a new instance of an element on every request.
See Eric Lippert's excellent series of "Immutability in C#": http://blogs.msdn.com/ericlippert/archive/tags/Immutability/C_2300_/default.aspx (you have to scroll down a bit)
As many of these answers show, there are many ways to make the collection itself immutable.
It takes more effort to keep the members of the collection immutable. One possibility is to use a facade/proxy (sorry for the lack of brevity):
class B
{
public B(int data)
{
this.data = data;
}
public int data
{
get { return privateData; }
set { privateData = value; }
}
private int privateData;
}
class ProxyB
{
public ProxyB(B b)
{
actual = b;
}
public int data
{
get { return actual.data; }
}
private B actual;
}
class A : IEnumerable<ProxyB>
{
private List<B> bList = new List<B>();
class ProxyEnumerator : IEnumerator<ProxyB>
{
private IEnumerator<B> b_enum;
public ProxyEnumerator(IEnumerator<B> benum)
{
b_enum = benum;
}
public bool MoveNext()
{
return b_enum.MoveNext();
}
public ProxyB Current
{
get { return new ProxyB(b_enum.Current); }
}
Object IEnumerator.Current
{
get { return this.Current; }
}
public void Reset()
{
b_enum.Reset();
}
public void Dispose()
{
b_enum.Dispose();
}
}
public void AddB(B b) { bList.Add(b); }
public IEnumerator<ProxyB> GetEnumerator()
{
return new ProxyEnumerator(bList.GetEnumerator());
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
The downside of this solution is that the caller will be iterating over a collection of ProxyB objects, rather than the B objects they added.
EDIT: Added support for edition contexts. Caller can only add elements inside an edition context. You can aditionally enforce that only one edition context can be created for the lifetime of the instance.
Using encapsulation you can define any set of policies to access the inner private member. The following example is a basic implementation of your requirements:
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Collections;
class B
{
}
interface IEditable
{
void StartEdit();
void StopEdit();
}
class EditContext<T> : IDisposable where T : IEditable
{
private T parent;
public EditContext(T parent)
{
parent.StartEdit();
this.parent = parent;
}
public void Dispose()
{
this.parent.StopEdit();
}
}
class A : IEnumerable<B>, IEditable
{
private List<B> _myList = new List<B>();
private bool editable;
public void Add(B o)
{
if (!editable)
{
throw new NotSupportedException();
}
_myList.Add(o);
}
public EditContext<A> ForEdition()
{
return new EditContext<A>(this);
}
public IEnumerator<B> GetEnumerator()
{
return _myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public void StartEdit()
{
this.editable = true;
}
public void StopEdit()
{
this.editable = false;
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
using (EditContext<A> edit = a.ForEdition())
{
a.Add(new B());
a.Add(new B());
}
foreach (B o in a)
{
Console.WriteLine(o.GetType().ToString());
}
a.Add(new B());
Console.ReadLine();
}
}
}
You basically want to avoid to give away references to the class B items. That's why you should do a copy of the items.
I think this can be solved with the ToArray() method of a List object. You need to create a deep-copy of the list if you want to prevent changes.
Generally speaking: most of the times it is not worthwhile to do a copy to enforce good behaviour, especially when you also write the consumer.
public class MyList<T> : IEnumerable<T>{
public MyList(IEnumerable<T> source){
data.AddRange(source);
}
public IEnumerator<T> GetEnumerator(){
return data.Enumerator();
}
private List<T> data = new List<T>();
}
The downside is that a consumer can modify the items it gets from the Enumerator, a solution is to make deepcopy of the private List<T>.
It wasn't clear whether you also needed the B instances themselves to be immutable once added to the list. You can play a trick here by using a read-only interface for B, and only exposing these through the list.
internal class B : IB
{
private string someData;
public string SomeData
{
get { return someData; }
set { someData = value; }
}
}
public interface IB
{
string SomeData { get; }
}
The simplest that I can think of is return a readonly version of the underlying collection if editing is no longer allowed.
public IList ListOfB
{
get
{
if (_readOnlyMode)
return listOfB.AsReadOnly(); // also use ArrayList.ReadOnly(listOfB);
else
return listOfB;
}
}
Personally though, I would not expose the underlying list to the client and just provide methods for adding, removing, and enumerating the B instances.
Wow, there are some overly complex answers here for a simple problem.
Have a private List<T>
Have an public void AddItem(T item) method - whenever you decide to make that stop working, make it stop working. You could throw an exception or you could just make it fail silently. Depends on what you got going on over there.
Have a public T[] GetItems() method that does return _theList.ToArray()