|
Both I guess; I just wonder why people think it faster to post a Google search into CP rather than the obvious place. Ho-hum.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Because it's easier to get us to do their thinking for them.
|
|
|
|
|
It was a rhetorical comment.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
But it deserved an answer.
|
|
|
|
|
Pete O'Hanlon wrote: But it deserved an answer. But, speaking rhetorically: is the answer it deserved ... deservedly ... rhetorical; or, would a rhetorical answer be just desserts ?
When I consider the brief span of my life, swallowed up in the eternity before and after, the little space which I fill, and even can see, engulfed in the infinite immensity of spaces of which I am ignorant, and which knows me not, I am frightened, and am astonished at being here rather than there; for there is no reason why here rather than there, now rather than then. Blaise Pascal
|
|
|
|
|
Hi there!
I need some help please; I am trying to parse an excel file and it is parsing all rows just fine except for the row that is set as currency format. This row is returning a null. Can somebody help please.
Thanks
Sameer
|
|
|
|
|
|
How are you trying to parse it? If you are reading direct from the Excel cell then chances are the content is simply a binary number.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I'm pulling in a sql table via linq to sql called "Employee".
There are a total of 11 fields within this Employee table, so my LINQ automatically creates properties such as the following:
Employee.Name
Employee.Address
Employee.Phone
etc...
I now however, need to add a child property to each of these properties called "Location", but I'm not sure how I would do this. So for example, I would need to use code such as the following:
Employee.Name.Location = 1;
Employee.Address.Location = 2;
Employee.Phone.Location = 3;
etc...
I know I could set this "Location" up directly within my linq to sql dbml file, however anytime I update my database, my dbml file would be overwritten, so I'd prefer to avoid that.
Is there any other way I can setup this "Location" child property?
Thanks.
|
|
|
|
|
Okay I just went cross eyed trying to relate Linq to database design. I'm sorry but I need to go back to the fundamental of the underlying data structure.
Create the following tables
Person
Locations/Addresses(these are probably the same thing as a Location will only have 1 address presumably.
PhoneNumbers has a foreign key PersonID
lnkPersonLocation - allows many to many links between location and person with a FK to both tables
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I have an abstract base class and two derived classes:- MyBase , MyFoo : MyBase , MyBar : MyBase .
I am creating readonly (and immutable) collections of MyFoo and MyBar :- MyFooCollection , MyBarCollection .
These are created by a one shot only factory method, so once instanciated the collection's contents will not change.
I would also like to provide, for convenience, a collection of MyBase :- MyBaseCollection which is a collation of all items in the other collections.
What would be your preferred method?
A. Create a MyBaseCollection on the fly each time it requested from the existing two collections.
B. Cache a MyBaseCollection and even though it is a duplication of the existing two collections.
C. Cache only a MyBaseCollection and create the other two collections on the fly from it.
D. Something else...
|
|
|
|
|
What do you need to do with it?
If you're only going to iterate over it (foreach), then I suggest a simple iterator that iterates one then the other -- the caller could cache the results if needed.
|
|
|
|
|
They are part of a class library. They implement IEnumerable<T> to provide the itterator over a private inner List<T> . That is really all they will expose apart from an indexer with getter only.
So, create a IEnumerable<MyBase> or MyBaseCollection the first time it's needed and cache it in case it's needed in future?
modified 15-Dec-11 16:07pm.
|
|
|
|
|
Here's a little something I whipped up to experiment.
A base class, two derived classes, and a list for each derived class:
private class C
{
public string Name { get ; private set ; }
public C ( string Name ) { this.Name = Name ; }
public override string ToString() { return ( this.Name ) ; }
}
private class A : C
{
public A ( string Name ) : base ( Name ) {}
}
private class B : C
{
public B ( string Name ) : base ( Name ) {}
}
private static System.Collections.Generic.List<A> alist = new System.Collections.Generic.List<A>() ;
private static System.Collections.Generic.List<B> blist = new System.Collections.Generic.List<B>() ;
An enumerator (or is it an iterator?) -- I think it would be in your base class and probably not take parameters:
private static System.Collections.Generic.IEnumerable<C>
All
(
params System.Collections.Generic.IEnumerable<C>[] lists
)
{
foreach ( System.Collections.Generic.IEnumerable<C> l in lists )
{
foreach ( C c in l )
{
yield return ( c ) ;
}
}
yield break ;
}
Then I can call it:
foreach ( C c in All ( alist , blist ) )
{
System.Console.WriteLine ( c ) ;
}
The code that does this could choose to cache the results if it needs to.
|
|
|
|
|
Interesting - I like it. I can't implement the code in exactly this way as this is a .Net 2 assembly so doesn't support covariance and contravariance, but I can acheive the same thing with a little more code. Thanks
[Edit] As the two existing collections are already stored and I know that's all I'll need I've put it all in a property and harcoded the collections - .NET 2 / C#<4 friendly:
public IEnumerable<MyBase> All
{
get
{
foreach (MyBase myBase in MyFooCollection)
yield return myBase;
foreach (MyBase myBase in MyBarCollection)
yield return myBase;
yield break;
}
}
modified 15-Dec-11 17:49pm.
|
|
|
|
|
Yes, that's what I imagined would work in your situation.
|
|
|
|
|
An enumerator has a state ("where am I?") which must be saved somewhere. If its state is inside the collection itself, you probably can't have two independent iterators at once, so things like:
foreach(someType a in collection) {
foreach (someType b in collection) {
if (a!=b) doSomeThingTo(a,b);
}
}
would fail. Having code accessing your collection from different threads through enumerators would fail too.
What I'm saying is, most of the time, IEnumerable (i.e. GetEnumerator ) requires you to create a new enumerator each time. It is too bad they called it such, CreateEnumerator would have been the better choice.
PS, FWIW: are you familiar with AsReadOnly?[^]
|
|
|
|
|
Good point Luc, thanks. I will look into this further.
Luc Pattyn wrote: FWIW: are you familiar with AsReadOnly?
Yes I am. The collections need to have internal constructors and an internal Add method so it was just as easy to create a simple base class (not the MyBase referred to in the OP) with this functionality that the other collections derive from.
|
|
|
|
|
Hi Davey,
If you did not use IList(s) (as Luc suggested) set to some Collection modified by the 'ReadOnly() method, as in:
public static IList<MyFoo> MyFoos;
MyFoos = MyFooCollection.AsReadOnly(); Then I am very curious what technique(s) you did use to make the Collections in your code ReadOnly.
thanks, Davey (and Luc)
When I consider the brief span of my life, swallowed up in the eternity before and after, the little space which I fill, and even can see, engulfed in the infinite immensity of spaces of which I am ignorant, and which knows me not, I am frightened, and am astonished at being here rather than there; for there is no reason why here rather than there, now rather than then. Blaise Pascal
|
|
|
|
|
Well a simple collection (generic) that is immutable (so naturally read only) just needs to accept items at instanciation, optionaly an indexer with a getter only defined and a count property - and of course implemeting IEnumerable<T> so it can be enumerated. Therefore a simple wrapper around List<T> suffices:
public class ImmutableCollection<T> : IEnumerable<T>
{
private List<T> innerList;
public ImmutableCollection(IEnumerable<T> collection)
{
innerList = new List<T>(collection);
}
public T this[int index]
{
get { return innerList[index]; }
}
public int Count
{
get { return innerList.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)innerList).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)innerList).GetEnumerator();
}
}
As the innerList is never exposed it is read only
Usage:
ImmutableCollection<string> collection = new ImmutableCollection<string>(new string[] { "A", "B", "C" });
Of course, the properties/fields of the the items contained will not be immutable, but that is the same as the ReadOnlyCollection<T> available from .AsReadOnly , but the minimum functionality only is exposed, and whatever you need to add can be created simply by accessing the inner list.
If necessary, the inner list could be made protected so it can be accessed directly in derived classes where concrete classes are desired or required.
|
|
|
|
|
+5 Thanks for this most enlightening answer !
When I consider the brief span of my life, swallowed up in the eternity before and after, the little space which I fill, and even can see, engulfed in the infinite immensity of spaces of which I am ignorant, and which knows me not, I am frightened, and am astonished at being here rather than there; for there is no reason why here rather than there, now rather than then. Blaise Pascal
|
|
|
|
|
encapsulation
|
|
|
|
|
How about getting the enumerator of each collection to enumerate both of them?
I have knocked up an example of the general outline of my classes, I have used this in the MyFooMyBarPool.MyBases property.
using System;
using System.Collections;
using System.Collections.Generic;
public enum BaseType
{
MyFoo,
MyBar
}
public abstract class MyBase
{
private BaseType baseType;
private string name;
internal MyBase(BaseType baseType, string name)
{
this.baseType = baseType;
this.name = name;
}
public string Name
{
get { return name; }
}
public override string ToString()
{
return string.Format("Type: {0}, Name: {1}", baseType, name);
}
}
public sealed class MyFoo : MyBase
{
internal MyFoo(string name)
: base(BaseType.MyFoo, name)
{ }
}
public sealed class MyBar : MyBase
{
internal MyBar(string name)
: base(BaseType.MyBar, name)
{ }
}
public class SimpleCollection<T> : IEnumerable<T>
{
private List<T> innerList;
public SimpleCollection(IEnumerable<T> items)
{
innerList = new List<T>(items);
}
public T this[int index]
{
get { return innerList[index]; }
}
public int Count
{
get { return innerList.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return innerList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return innerList.GetEnumerator();
}
}
public class MyFooCollection : SimpleCollection<MyFoo>
{
internal MyFooCollection(IEnumerable<MyFoo> myFoos)
: base(myFoos)
{ }
}
public class MyBarCollection : SimpleCollection<MyBar>
{
internal MyBarCollection(IEnumerable<MyBar> myBars)
: base(myBars)
{ }
}
public class MyFooMyBarPool
{
private MyFooCollection myFooCollection;
private MyBarCollection myBarCollection;
public MyFooMyBarPool()
{
myFooCollection = new MyFooCollection(new MyFoo[] { new MyFoo("A"), new MyFoo("B"), new MyFoo("C") });
myBarCollection = new MyBarCollection(new MyBar[] { new MyBar("A"), new MyBar("B"), new MyBar("C") });
}
public IEnumerable<MyBase> MyBases
{
get
{
IEnumerator<MyFoo> myFooEnumerator = myFooCollection.GetEnumerator();
while (myFooEnumerator.MoveNext())
yield return myFooEnumerator.Current;
IEnumerator<MyBar> myBarEnumerator = myBarCollection.GetEnumerator();
while (myBarEnumerator.MoveNext())
yield return myBarEnumerator.Current;
yield break;
}
}
public MyFooCollection MyFoos
{
get { return myFooCollection; }
}
public MyFooCollection MyBars
{
get { return myFooCollection; }
}
}
class Program
{
static void Main(string[] args)
{
MyFooMyBarPool pool = new MyFooMyBarPool();
foreach (MyBase myBase in pool.MyBases)
Console.WriteLine(myBase);
Console.WriteLine(
"{0} MyFoo and {1} MyBar items",
pool.MyFoos.Count, pool.MyBars.Count);
Console.ReadKey();
}
}
|
|
|
|
|
Sorry Dave, it's too early a day to study all that in any detail. As I didn't see any new or Create in there (I may have overlooked them), I doubt it can be correct. If you want to offer simultaneous iterator-like operations to a collection, then the state of the iterator is bound to be outside said collection.
You can simply test using this:
int count1=0;
foreach(someType element in collection) count1++;
int count2=0;
foreach(someType element1 in collection) {
foreach(someType element2 in collection) {
count2++;
}
}
if (count2!=count1*count1) noGood();
|
|
|
|
|
DaveyM69 wrote: How about getting the enumerator
It seems you're still looking at it in the wrong way, when implemented properly there isn't just one enumerator to a collection, there are as many as you want (and that is why they need storage space outside the collection, hence a new action somewhere).
GetEnumerator returns an enumerator, not the enumerator.
|
|
|
|
|