|
Ed.Poore wrote: is this possible in C++?
As if I'd know. I only dabbled in C++, I've spent most of my career (so far) in C, I only started doing C# because the only OpenVMS jobs I saw used COBOL.
Ed.Poore wrote: more details
Yeah, I'll work up a little example of what I have so far.
|
|
|
|
|
PIEBALDconsult wrote: Yeah, I'll work up a little example of what I have so far.
Yeah that'll help quite a bit.
PIEBALDconsult wrote: As if I'd know.
Well I'd probably know less, again only dabbling. Mainly C# but a bit of VB6 and quite a lot of C depending on the projects.
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
I can't think of any simpler examples so I'll just describe what I'm doing.
I'm writing a generic pool. Each item in the pool gets wrapped and added to a HashSet. The class is therefore a factory of these items as well. So, because it's a factory and there shouldn't be more than one pool of a given type in the appdomain, making the class a singleton seems appropriate.
public class GenericPool<T>
where T : class , new()
{
private sealed class GenericPoolItem : IGenericPoolItem<T>
{
private T item = new T() ;
}
private static readonly System.Collections.Generic.HashSet<GenericPoolItem> items =
new System.Collections.Generic.HashSet<GenericPoolItem>() ;
private static readonly System.Collections.Generic.List<GenericPoolItem> freelist =
new System.Collections.Generic.List<GenericPoolItem>() ;
public static IGenericPoolItem<T>
Reserve
{
get
{
GenericPoolItem result = null ;
lock ( items )
{
if ( freelist.Count == 0 )
{
result = new GenericPoolItem() ;
items.Add ( result ) ;
}
else
{
result = freelist [ 0 ] ;
freelist.RemoveAt ( 0 ) ;
}
}
result.Reserve() ;
return ( result ) ;
}
}
}
There is also an interface to expose only two members of the wrapper; Value and Free.
To use the class(es), one need only call Reserve, use the wrapped item, and then Free the wrapped item.
IGenericPoolItem<Widget> item = GenericPool<Widget>.Reserve ;
item.Free() ;
(I'll likely rename Reserve or change it to a method; it looks wrong as it is.)
For that I could use a static class, but as mentioned, I want to be able to derive.
Why? Well, one of the particular types I want to pool is StringBuilder (I still have yet to determine whether or not there's any performance benefit of that).
In the above snippet, Widget could be StringBuilder and it will work just fine except I would need to clear the StringBuilder each time I Reserve it. If I derive, I can override (kinda sorta) Reserve to perform the clearing.
public class StringBuilderPool : PIEBALD.Types.GenericPool<System.Text.StringBuilder>
{
public new static PIEBALD.Types.IGenericPoolItem<System.Text.StringBuilder>
Reserve
{
get
{
PIEBALD.Types.IGenericPoolItem<System.Text.StringBuilder> result =
PIEBALD.Types.GenericPool<System.Text.StringBuilder>.Reserve ;
result.Value.Length = 0 ;
return ( result ) ;
}
}
}
The classes work as I want. But in order to derive, the base class can't have a private constructor (which is usual for a singleton), the deriving class needs access to the base class' constructor, so I make it protected. But a deriving class could make its constructor public, undoing my efforts.
My solution is to have the constructor throw an exception:
protected GenericPool
(
)
{
throw ( new System.InvalidOperationException
( "Instantiating GenericPool is forbidden." ) ) ;
}
but I would prefer a compile-time error or something less heavy-handed.
I could, of course, just let people instantiate it, but the instances would be fairly useless without instance members... always remembering that probably no one else will use this anyway.
|
|
|
|
|
PIEBALDconsult wrote: always remembering that probably no one else will use this anyway.
In that instance I think you're probably overcomplicating things
How about moving the Reserve method to the GenericPoolItem , or rather provide the common stuff inside the container class and then provide the option to perform additional operations. For example if you do something like the following:
public static IGenericPoolItem<T> Reserve<T>()
{
if (T is ICustomReserve)
{
((ICustomReserve)default(T)).Reserve();
}
} Thus if you want to provide additional reserving you create a "wrapper" item and provide the implementation from there. Note the code would probably need rethinking but perhaps it provides some food for thought?
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
Ed.Poore wrote: probably overcomplicating things
Probably, but I try to encapsulate the overcomplications.
The Item does have a Reserve, but it only sets its reserved boolean. An earlier implementation allowed deriving the item wrapper, which allowed overriding the item wrapper's Reserve method, but I decided I prefer to keep the item wrapper private.
I also considered the ability to provide delegates to add functionality, something like after-new and after-reserve, but I haven't sold myself on the idea yet.
|
|
|
|
|
PIEBALDconsult wrote: Probably, but I try to encapsulate the overcomplications.
I suffer from the same problems, over-complicating things. After reading Mark Pilgrim's book "Dive into Python" and the section on unit testing I've got to say that I like his approach, write the minimal code to pass the first test and then add a bit more passing each test.
Unfortunately the work which I do doesn't lend itself to "easy" unit testing, from what I've read it requires all kinds of mock objects etc and I just haven't learnt any of that stuff yet. I'm only now using Subversion consistently across all projects
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
Ed.Poore wrote: only now using Subversion
Then you're ahead of me. I was going to install it, I read most of the manual, but then my colleague installed it so I lost interest. Part of the problem is that on a previous job we used CMS (the OpenVMS layered product) and I don't want to lower my standards.
|
|
|
|
|
Well I've got to say it's fantastic so far, I've bought a license for VisualSVN[^] and installed their "server" onto both my laptop and server and just use those. Having everything built into VS2008 is great.
norm.net and I are working on a joint project and using Assembla[^] as a repository. He's spent most of the time setting up workflows etc and really likes it, I haven't tried it yet. He's also installed AnkhSVN as opposed to VisualSVN (free opposed to £30) and he likes it, I only tried it a few years ago and it was more or less dead so hadn't expected it to have moved on but apparently it's working well. Personally I prefer VisualSVN because it uses Tortoise rather than rewriting it all, but then again I haven't tried Ankh so can't comment.
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
Although aimed at C++ this article[^] mentions something about deriving classes, haven't read through the article but might be worth a shot, the author appears to know what he's talking about.
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
I think the advent of static classes in .net widens the definition of Singleton somewhat.
A static class actually has zero instances, but otherwise fulfills the role.
So maybe the definition of Singleton needs to be broadened to "no more than one instance".
At any rate, I decided to simply make the class static and have events (OnNew, OnReserve, and OnFree) so the user can add special handling as desired.
PIEBALD.Types.GenericPool<System.Text.StringBuilder>.OnReserve +=
delegate
(
System.Text.StringBuilder Subject
)
{
Subject.Length = 0 ;
return ;
} ;
|
|
|
|
|
That probably makes more sense.
I doubt it. If it isn't intuitive then we need to fix it. - Chris Maunder
|
|
|
|
|
make it abstract
|
|
|
|
|
But I still want to keep derived classes from being instantiateable as well.
|
|
|
|
|
Yeach, I need that too. Unfortunately it seems that there is no way to
1.) Override static methods/properties
2.) Inherit from static classes
3.) Force particular static members by interface
Greetings - Gajatko
Portable.NET is part of DotGNU, a project to build a complete Free Software replacement for .NET - a system that truly belongs to the developers.
|
|
|
|
|
gajatko wrote: 1.) Override static methods/properties
Override , no, but you can make a new implementation.
gajatko wrote: 2.) Inherit from static classes
gajatko wrote: 3.) Force particular static members by interface
Which is why I can't use a static class for this.
|
|
|
|
|
public abstract class MyClassNname
At that point, it MUST be derived from in order to use it.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Yes, but that's not entirely what I want. I want a derivable singleton. The base class is a singleton*, and any derived classes must also be singletons.
* Using a loose definition of "singleton", that considers a class with only static members as the zeroth instance.
modified on Monday, June 16, 2008 4:06 PM
|
|
|
|
|
Hi All,
I have a routine i'm working on that parses a file looking for chunk information. There are various possible chunks and some chunk types (that I have defined as structs) can sometimes occur more than once in any given file.
What is the best solution for having a single collection that can hold all/any of these created structs? Can I define a generic collection like:
List<Object> _wavinfo = new List<Object>();
I've not worked like this before, would be good to know if this is a sound idea or if there is a better method. Would it be better to have a strict definition of the object I know will only be created once and List<T> for the object I know might occur more than once?
I'm basically trying to keep the memory footprint as low as possible.
Cheers,
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
List<object> works fine for that.
But using classes (rather than structs) with a common base class may be somewhat better.
Jammer wrote: I'm basically trying to keep the memory footprint as low as possible.
You probably needn't worry about that.
|
|
|
|
|
Hi,
Gotca, thanks for that, I started progressing with a List<object> . The problem is the similarity between these chunks is limited to just the ID of each chunk, after that they are all completely different in structure making a base class tiny. Or am I missing the point?
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Then stick with the List<object> unless you think someone may put something else in the List.
It kinda depends on what you need to do with the things.
|
|
|
|
|
How do I change the text of a window? I read the article regarding Window Tabifier and tried using the code. However, this produced read-only results.
Thanks in advance.
|
|
|
|
|
You can use SetWindowText Function[^] You will need some P/Invoke to get it working, I'm sure www.pinvoke.net has some examples.
That Asian Guy wrote: I read the article regarding Window Tabifier and tried using the code. However, this produced read-only results.
Yes, the class I used in that application has read only properties. You can however extend it for your needs.
Giorgi Dalakishvili
#region signature
my articles
#endregion
|
|
|
|
|
Thanks, is there a way to change the icon as well?
|
|
|
|
|
I'm not aware of a function that changes icon of window
Giorgi Dalakishvili
#region signature
my articles
#endregion
|
|
|
|