|
I had a similar problem once. (But I was more stubborn keeping it Generic)
So what i ended up doing was keeping with the object types, using that to filter each value and tryparse into decimal List class so that I could sum up everything. I just had to prepare for the worse so I put in my catch that if any error would occur to throw out the value and just log what went wrong, so that way when I picked up more errors (Which I did not much), i could just improve the tryparse
Loading signature...
. . . Please Wait . . .
|
|
|
|
|
You could do it by using a class that does the adding. You would need to specify the class to do the adding and the type it uses in the moving averages class.
Something like this:
public interface IArithmetic<T>
{
T Add(T augend, T addend);
}
public class GenericAdd<T, U> where T : IArithmetic<U>, new()
{
T adder = new T();
public U AddGenericTypes(U augend, U addend)
{
return adder.Add(augend, addend);
}
}
And for each type you want to use this with you will need one of these.
public class AddInt : IArithmetic<int>
{
public AddInt()
{
}
#region IArithmetic<int> Members
public int Add(int augend, int addend)
{
return augend + addend;
}
#endregion
}
These can then be used like this:
GenericAdd<AddInt, int> intAdder = new GenericAdd<AddInt, int>();
int result = intAdder.AddGenericTypes(1, 2);
Seems like a lot of work to me unless you know you are going to need it.
|
|
|
|
|
You could of course go the fully OO route and make your own "number" class. I.e. the way you'd have done it prior to generics. Then add some implied conversion overloads so you don't need to manually type-cast your int/double/decimal/etc. You could then even accommodate other more complicated data types (e.g. to generate moving averages on a candle-stick-chart with 3 values per item: open, avg, close).
BTW, for the data sample I'd go with either a double linked list (LinkedList<t> with max length) or a circular array, not an Array List as you've done in your sample code (that's implemented as a flat array so a remove from index 0 means it shifts all samples down by 1, if you reverse the order then each insert would shift all items up by 1). Seeing as mostly you'd calculate by iterating over each item in the "list" and you'd not want to move all the samples in the array each time you get a new one the linked list should suffice for this purpose. The circular array I'd only use if I know the size sample will not change after initially creating the object and if I need to reference specific items by index.
You could use a Queue<t> type for this, as well. I "think" it's implemented as a linked list anyway.
Here's what I'm thinking:
public class MyNumber {
private object _value;
public object Value {
get { return _value; }
set {
if ((value is int) || (value is double) || (value is decimal))
_value = value;
else throw new InvalidCastException();
}
}
public MyNumber(object val) {
Value = val;
}
public static implicit operator MyNumber(int val) { return new MyNumber(val); }
public static implicit operator int(MyNumber val) { return (int)val._value; }
public static implicit operator MyNumber(double val) { return new MyNumber(val); }
public static implicit operator double(MyNumber val) { return (double)val._value; }
public static implicit operator MyNumber(decimal val) { return new MyNumber(val); }
public static implicit operator decimal(MyNumber val) { return (decimal)val._value; }
}
public class MovingAverage {
private LinkedList<MyNumber> _samples = new LinkedList<MyNumber>();
private decimal total = 0;
public int SampleSize { get; private set; }
public decimal Value {
get {
if (SampleSize < 0) return (_samples.Count > 0) ? total / _samples.Count : 0;
return (_samples.Count >= SampleSize) ? total / (decimal)SampleSize : 0;
}
}
public MovingAverage(int sampleSize = -1) {
SampleSize = sampleSize;
}
public void Add(MyNumber value)
{
_samples.AddLast(value);
total += value;
if (SampleSize > 0) {
while (_samples.Count > SampleSize) {
total -= _samples.First;
_samples.RemoveFirst();
}
}
}
}
Edit: Stupid me that type check should have been or's not and's
modified 10-Feb-14 7:03am.
|
|
|
|
|
'Griff, I don't know if anyone else has said this, but: source control is your friend. Check-in early, check-in often.
Software Zen: delete this;
|
|
|
|
|
I don't like to check in "partial" or non-working code. That's why I have hourly incremental backups on my PC - so I can only lose 60 minutes work (in theory - practice shows that it's normally quicker to regenerate than restore for an hour or so ago)
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Everyone has their own workflow that's best for them.
That said, a lot of my team members make copies of working files, rather than use source control as a tool. I work with one guy who tends to keep everything checked out, and only checks in prior to doing a build for distribution. It drives me nuts, because he'll have days or even weeks worth of work that exists only on his machine (our source control data base gets backed up daily). I'm tempted to power off his machine and substitute a bad hard drive to teach him a lesson .
My approach, at least in our development branches, is to work incrementally and check-in each successful increment. Most of the time I make the feature I'm working on disabled/invisible/inactive in release builds, until I think it's ready. This makes backtracking, which I do a lot more than I'd like to admit, simpler. Diff's are handy too when I've led myself down the proverbial garden path .
Software Zen: delete this;
|
|
|
|
|
Gary Wheeler wrote: Everyone has their own workflow that's best for them.
Very true.
It's a fine balance, I think: I don't like a checked in version that won't run, or throws continual NotImplementedExceptions, and I try to avoid thinking of version control as a backup system!
Instead I have my NAS and automatic incremental backups that I don't even see, much less think about.
I can understand both you and your team member's position: he doesn't want to issue code that he isn't sure is final in case it gets used and has to become final by default. But you want it backed up so weeks can't be lost... Perhaps a "proper" backup system for your PCs to work alongside the SVN/GIT route would be useful? I know damn well I wouldn't want to have to rebuild my current PC without good backups - it would take me days to get the software all back on and configured!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
We do have a backup system available; it requires some individual initiative to use it. Some do, some don't. Based on prior experience, our herd of cats doesn't work well with an automated backup mechanism.
OriginalGriff wrote: SVN/GIT If only. We're still using SourceSafe, believe it or not. One of my 'spare time' projects (yeah, right) is to get our source control moved to something else this year. Current candidates are MS Team Foundation and SourceGear Vault. My uninformed impression is that Git wouldn't work for us, based on its apparent complexity.
Software Zen: delete this;
|
|
|
|
|
Rebuild PC? Oh. Right. Mine's a company XP machine. The fun should all kick off in about a month.
|
|
|
|
|
I meant when the HDD goes south, as it will one day. But upgrade the PC / OS and you get a long job as well...
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
There a issue on Connect to add IArithmetic interface to the value types, but it seems to be going nowhere.
https://connect.microsoft.com/VisualStudio/feedback/details/94264/arithmetic-types-like-int-double-decimal-should-implement-iarithmetic-t
(NOTE: for some reason, going to that link gives an error -- Other issues are displaying OK)
Truth,
James
|
|
|
|
|
You can use the System.Linq.Expressions namespace to create generic operators quite easily. For example, see Marc Gravell's Generic Operators[^] from the MiscUtil library[^].
public static class GenericOperator<T>
{
private static Func<T, T, TResult> CreateCore<TResult>(Func<Expression, Expression, BinaryExpression> body)
{
try
{
Type typeT = typeof(T);
var left = Expression.Parameter(typeT, "left");
var right = Expression.Parameter(typeT, "right");
if (typeT.IsEnum)
{
Type enumType = Enum.GetUnderlyingType(typeT);
var x = Expression.Convert(left, enumType);
var y = Expression.Convert(right, enumType);
Expression op = body(x, y);
if (op.Type == enumType) op = Expression.Convert(op, typeT);
return Expression.Lambda<Func<T, T, TResult>>(op, left, right).Compile();
}
return Expression.Lambda<Func<T, T, TResult>>(body(left, right), left, right).Compile();
}
catch (InvalidOperationException ex)
{
string message = ex.Message;
return delegate { throw new InvalidOperationException(message); };
}
catch (ArgumentException ex)
{
string message = ex.Message;
return delegate { throw new InvalidOperationException(message); };
}
}
private static Lazy<Func<T, T, TResult>> Create<TResult>(Func<Expression, Expression, BinaryExpression> body)
{
return new Lazy<Func<T, T, TResult>>(() => CreateCore<TResult>(body), true);
}
private static readonly Lazy<Func<T, T, T>> _add = Create<T>(Expression.Add);
public static Func<T, T, T> Add
{
get { return _add.Value; }
}
...
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Overloaded operators? Can we do those? In C#?
|
|
|
|
|
Yep! But not in generics...the generic parameter (as far as the compiler is concerned) derives directly from object unless it is constrained so you can't use methods other than those that apply to object .
And you can't constrain to basic types...There's an interesting interview covering this here: http://www.artima.com/intv/generics.html[^]
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
You know, sometimes going backwards it's the only way to go forward.
|
|
|
|
|
I had exactly the same issue a few years ago when I built a ring buffer class to calculate a moving average.
Indeed, it would be nice to be able to have something like an INumeric interface or a way to filter generics which can support arithmetic!
In the end I just used double s, which was more than OK for my specific needs and allowed me to use the same class with int s and such.
In theory, there is no difference between theory and practice, but not in practice. - Anonymous
A computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are, in short, a perfect match. - B. Bryson
|
|
|
|
|
Rick York has posted a new comment at "article "Fastest hash function for table lookups in C?!"":
This is a very poor excuse for an article.
What's the problem Mr. York?
For third time you downvote me without pointing out what you don't like or rather hate - your last vote being 1.
Get down get down get down get it on show love and give it up
What are you waiting on?
|
|
|
|
|
Um. I see no comments at all: Fastest hash function for table lookups in C?![^] and you have no "1" votes on that article: just 4 and 5s.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Probably someone with enough rights deleted his vote, but I don't care about votes I should like to know what Rick saw so bad to give 1 - I guess if there were lower vote he would use it.
Get down get down get down get it on show love and give it up
What are you waiting on?
|
|
|
|
|
Probably because it is a dump of stats: remove that and there is nothing left. You have to explain what you are doing - simply showing the results is not what makes an article. You may be getting up votes either in protest at him not telling you what was the actual problem or because the results are so damn clever that nothing needs explaining (doubtful).
It should have been a blog post: not an article.
"If you think it's expensive to hire a professional to do the job, wait until you hire an amateur." Red Adair.
Those who seek perfection will only find imperfection
nils illegitimus carborundum
me, me, me
me, in pictures
|
|
|
|
|
>... not telling you what was the actual problem or because the results are so damn clever that nothing needs explaining (doubtful).
I see no problem(s) at all, that's why I am asking.
>It should have been a blog post: not an article.
Are you sure, I am not - something as general and important as hashing for lookups deserves special page.
Get down get down get down get it on show love and give it up
What are you waiting on?
|
|
|
|
|
Sanmayce wrote: I see no problem(s) at all, that's why I am asking.
I've told you what the problem is: this is not an article: it is a blog post, at best.
Sanmayce wrote: Are you sure, I am not
Yes.
Sanmayce wrote: something as general and important as hashing for lookups deserves special page
Perhaps: in that case, write a proper article and don't just dump images on the page. Explain the why's and wherefore's of what you are doing.
If you don't know what a good article should look like go and search for anything written by Marc Clifton or Sasha Barber: they both write well presented and easy to read articles.
Good luck.
"If you think it's expensive to hire a professional to do the job, wait until you hire an amateur." Red Adair.
Those who seek perfection will only find imperfection
nils illegitimus carborundum
me, me, me
me, in pictures
|
|
|
|
|
>I've told you what the problem is: this is not an article: it is a blog post, at best.
Okay, I am not arguing, my point was and still is that by sharing some etude it must be useful in first place and hopefully well described where I fail to do so too many times I guess.
>Explain the why's and wherefore's of what you are doing.
See, this is a simple 20 lines C code doing the most well-known task among all general etudes - returning a 32bit value out of smoe key. I didn't want to repeat how to bake bread, just to share the source and stats on different machines in order to give the reader an idea of is it worth downloading?
I just looked at article "Sorting Algorithms In C#" by Mr. Clifton and in my humble (I am not a programmer) opinion it appears to me useless, simply it doesn't cover the most interesting and useful area of sorting - the external ones e.g. I have had some drafts in C that dealt with 1,000,000,000 keys VERY FAST, with mentioning this I just wanted to share how different opinions exist.
>Good luck.
Thank you, obviously my articles are not even articles, sorry, but blame me not - that's me, a C amateur trying to test/share interesting etudes.
Get down get down get down get it on show love and give it up
What are you waiting on?
|
|
|
|
|
It is a blog post, at best. It is not an article.
Sanmayce wrote: Thank you, obviously my articles are not even articles, sorry, but blame me not - that's me, a C amateur trying to test/share interesting etudes.
This one is not an article, plain and simple.
"If you think it's expensive to hire a professional to do the job, wait until you hire an amateur." Red Adair.
Those who seek perfection will only find imperfection
nils illegitimus carborundum
me, me, me
me, in pictures
|
|
|
|
|
Mark is correct, it's a very poorly produced article. No explanation of anything and the 'poem' at the end has no place at all.
Veni, vidi, abiit domum
|
|
|
|
|