I have an existing application with objects like so.
class MyObject{
public MyCollection TypeOnes;
public MyCollection TypeTwos;
public MyCollection TypeThrees;
public MyCollection All;
}
class MyCollection : Collection{
public boolean IsLoaded;
}
And it is loaded like this.
//using bool array for flag simplicity in example
public void Load(ref MyObject obj, bool[] flags){
if(flags[0]){
obj.TypeOnes = LoadOnes();
obj.TypeOnes.IsLoaded = true;
}else{
obj.TypeOnes = new MyCollection();
}
if(flags[1]){
obj.TypeTwos = LoadTwos();
obj.TypeTwos.IsLoaded = true;
}else{
obj.TypeTwos= new MyCollection();
}
if(flags[2]){
obj.TypeThrees = LoadThrees();
obj.TypeThrees.IsLoaded = true;
} else {
obj.TypeThrees = new MyCollection();
}
if(flags[3]){
obj.All = obj.TypeOnes.Clone().AddRange(obj.TypeTwos.Clone()).AddRange(obj.TypeThrees.Clone());
obj.All.IsLoaded = true;
} else {
obj.All = new MyCollection();
}
}
As you can plainly see the All collection that is supposed to represent all of the Types will be out of sync unless all types are loaded at once with the All collection.
What I'm going to do is make a single flag to load all of the type collections, however, I would like to keep the All collection to use to access all of the Type Collections at once and have them in sync in order to limit the amount of refactoring I'm going to have to do. I want it to be read/write so that if I make a change to the TypeOnes collection it will be reflected in the All collection and vice versa.
Is there an existing DataType that I can use for this?
If not what kind of data structure am I looking to build?
Unless you have a specific reason to create a clone of the objects in the three contained collection, why not implement All as an IEnumerable<T> (or IEnumerable if you're using pre-generic .NET), something like:
// Option: Preserve duplicates between collections
public IEnumerable<T> All()
{
// Ensure child collections are loaded
return TypeOnes.Concat(TypeTwos).Concat(TypeThrees);
}
// Option remove duplicates between collections
public IEnumerable<T> All()
{
// Ensure child collections are loaded
return TypeOnes.Union(TypeTwos).Union(TypeThrees);
}
That way the existing code contract for adding things to the contained collections is maintained, and you are ensured that All is never stale or out of sync with those collections.
Note that with the old code contract, All became out of sync with the contained collections after it was initialized (since updates to the children were not reflected into All). This is a change in behavior that may or may not be acceptable.
How about something like this? Concat will merge the collections and return all of them at once.
class MyObject
{
public MyCollection TypeOnes;
public MyCollection TypeTwos;
public MyCollection TypeThrees;
public IEnumerable<T> All
{
get { return TypeOnes.Concat(TypeTwos.Concat(TypeThrees));}
// You can use Union() to handle duplicates as well, but it's slower.
}
}
Possible approach - expose "all" as IEnumerable<Base_type_for_items_in_other_collections> and create it on demand by concatenating other collections. I.e. if you have small list of collections basic Enumerable.Concat would work:
public IEnumerabe<MyObject> All {get
{
return TypeOnes.Concat(TypeTwos.Concat(TypeThrees));
}}
All you really need is an ICollection interface or IEnumerable interface that covers all your other collections in a union, right? I assume you won't be adding items to the All collection once you've loaded everything. If that's the case, try:
For the declaration of All:
public IEnumerable<MyBaseType> All;
To set All:
obj.All = System.Linq.Enumerable.Concat<MyBaseType>(
obj.TypeOnes, obj.TypeTwos).Concat(obj.TypeThrees);
That should allow All to reflect changes in the other collections even if it doesn't allow you to add items directly to it.
Since there might be a lot of items you can consider yield return to return items so caller can stop accessing items when appropriate limit were reached/item was found.
public class MyObject
{
public MyCollection TypeOnes { get; set;}
public MyCollection TypeTwos { get; set;}
public MyCollection TypeThrees { get; set;}
public IEnumerable<string> All
{
get
{
foreach (var item in TypeOnes.Union(TypeTwos).Union(TypeThrees))
{
yield return item;
}
}
}
}
public class MyCollection : Collection<string>
{
public bool IsLoaded { get; set; }
}
Related
Assuming the following piece of code that caches two collections of objects MyObject: one collection is of type IEnumerable<MyObject> and the other one is of type List<MyObject>. The code retrieves the values from the cache and then accesses the collection:
class Program
{
static void Main(string[] args)
{
CacheManager.CacheSomething();
}
public class MyService
{
private IEnumerable<AnObject> AnObjects
{
get
{
return new[]
{
new AnObject {MyString1 = "one", MyString2 = "two"},
new AnObject {MyString1 = "three", MyString2 = "four"}
};
}
}
public IEnumerable<AnObject> GetEnumerable()
{
return AnObjects;
}
public List<AnObject> GetList()
{
// Run it out to a list
return AnObjects.ToList();
}
}
public static class CacheManager
{
public static void CacheSomething()
{
// Get service
var service = new MyService();
// Get the values as List and Enumerable
var list = service.GetList();
var enumerable = service.GetEnumerable();
// Putting them in a cache
HttpRuntime.Cache.Insert("list", list);
HttpRuntime.Cache.Insert("enumerable", enumerable);
// Get the values
var retrievedList = HttpRuntime.Cache["list"] as List<AnObject>;
var retrievedEnumerable = HttpRuntime.Cache["enumerable"] as IEnumerable<AnObject>;
// Access both
var res1 = retrievedList.ToList();
var res2 = retrievedEnumerable.ToList();
}
}
public class AnObject
{
public string MyString1 { get; set; }
public string MyString2 { get; set; }
}
}
Is there a difference in terms of the amount of memory required to store these objects based on the collection types?
The reason that I ask is that when we have been profiling our applications and we've noticed that when we look at the dependency tree, the IEnumerable has the Service associated with it. Does that mean that it caches the service too?
Can anyone shed some light as to whether this is a cause for concern? Is it a problem to store an IEnumerable in the cache? Should we prefer caching Lists over IEnumerables?
And IEnumerable is not data. It is a promise that you will receive data when you ask. Some data might implement it (arrays, lists) but sometimes, it's not materialized data but instead a query to a database.
"Caching" your IEnumerable means you cache the knowledge where to get data. That's not what you want. You want to cache the data itself.
Always materialize your IEnumerables before caching the result (for example with ToList or ToArray). Otherwise, you might end up with a cache that just holds a procedure that is called to get you the data.
The fact that the IEnumerable in your example still holds a reference to the service is exactly that: it does not hold data, it holds the reference to the service and will call it again when you use it. So the exact opposite of what you want from the cache.
Difference in amount of memory? No.
Why? IEnumerable is not a type; it's an interface. That means that anything stored in an IEnumerable is actually some other type that implements IEnumerable (like List, for example).
IEnumerable only forces implementation of methods to read the list. It's not appropriate for modifying the collection. That's why you would want to cast it to the actual type (like List), so you can use methods like Add.
In general terms, a program I'm making involves storing a small number of entries (probably less than 30 at any given time) which can be categorized. I want to allow these entries to be seen but not altered from outside the class using them. I made a class called Entry which could be modified and another called ReadOnlyEntry which is a wrapper for an Entry object. The easiest way to organize these Entry objects it seems is to create a List<List<Entry>>, where each List<Entry> is a category. But then exposing that data in a readonly way became messy and complicated. I realized I would have to have one object of each of the following types:
List<List<Entry>> data;
List<List<ReadOnlyEntry>> // Where each ReadOnlyEntry is a wrapper for the Entry in the same list and at the same index as its Entry object.
List<IReadOnlyCollection<ReadOnlyEntry>> // Where each IReadOnlyCollection is a wrapper for the List<ReadOnlyEntry> at the same index in data.
IReadOnlyCollection<IReadOnlyCollection<ReadOnlyList>> readOnlyList // Which is a wrapper for the first item I listed.
The last item in the list would be exposed as public. The first lets me change entries, the second lets me add or delete entries, and the third lets me add or delete categories. I would have to keep these wrappers accurate whenever the data changes. This seems convoluted to me, so I'm wondering if there's a blatantly better way to handle this.
Edit 1:
To clarify, I know how to use List.asReadOnly(), and the stuff I proposed doing above will solve my problem. I'm just interested in hearing a better solution. Let me give you some code.
class Database
{
// Everything I described above takes place here.
// The data will be readable by this property:
public IReadOnlyCollection<IReadOnlyCollection<ReadOnlyList>> Data
{
get
{
return readOnlyList;
}
}
// These methods will be used to modify the data.
public void AddEntry(stuff);
public void DeleteEntry(index);
public void MoveEntry(to another category);
public void AddCategory(stuff);
public void DeleteCategory(index);
}
You can use List<T>.AsReadOnly() to return ReadOnlyCollection<T>.
Also, you're torturing the List<T> class storing the data the way you are. Build your own hierarchy of classes which store your individual lists.
.NET collections should support covariance, but they don't support it themselves (instead some interfaces support covariance https://msdn.microsoft.com/ru-ru/library/dd233059.aspx). Covariance means List<Conctrete> behaves like subclass of List<Base> if Concrete is subclass of Base. You can use interfaces covariation or just use casting like this:
using System.Collections.Generic;
namespace MyApp
{
interface IEntry
{
}
class Entry : IEntry
{
}
class Program
{
private List<List<Entry>> _matrix = null;
public List<List<IEntry>> MatrixWithROElements
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public IReadOnlyList<List<IEntry>> MatrixWithRONumberOfRows
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public List<IReadOnlyList<IEntry>> MatrixWithRONumberOfColumns
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry) as IReadOnlyList<IEntry>);
}
}
public IReadOnlyList<IReadOnlyList<IEntry>> MatrixWithRONumberOfRowsAndColumns
{
get
{
return _matrix.ConvertAll(row => row.ConvertAll(item => item as IEntry));
}
}
public void Main(string[] args)
{
}
}
}
Thanks to Matthew Watson for pointing on errors in my previous answer version.
You could make an interface for Entry which contains only getters; you would expose elements via this interface to provide read-only access:
public interface IEntry
{
int Value { get; }
}
The writable implementation would be simply:
public sealed class Entry : IEntry
{
public int Value { get; set; }
}
Now you can take advantage of the fact that you can return a List<List<Entry>> as a IReadOnlyCollection<IReadOnlyCollection<IEntry>> without having to do any extra work:
public sealed class Database
{
private readonly List<List<Entry>> _list = new List<List<Entry>>();
public Database()
{
// Create your list of lists.
List<Entry> innerList = new List<Entry>
{
new Entry {Value = 1},
new Entry {Value = 2}
};
_list.Add(innerList);
}
public IReadOnlyCollection<IReadOnlyCollection<IEntry>> Data => _list;
}
Note how simple the implementation of the Data property is.
If you need to add new properties to IEntry you would also have to add them to Entry, but you wouldn't need to change the Database class.
If you're using C#5 or earlier, Data would look like this:
public IReadOnlyCollection<IReadOnlyCollection<IEntry>> Data
{
get { return _list; }
}
I know similar questions have been asked before, but I've come to a dead end while trying to find the best design pattern I can use.
I am trying to make a class-library with a factory class that provides enumerators for different items via method calls.
Note: Those items don't exist in a collection and can only be created knowing the previous one. (e.g. x(i) = x(i-1) + θ) Because of that I cannot implement those items as IEnumerable(s)
What I thought until now:
public static class AllItems {
public sealed class ItemsEnumerator: IEnumerator<Item>{
//those classes have non-public constructors
.....
}
public static ItemsEnumerator GetItemsEnumerator() {
return new ItemsEnumerator();
}
public sealed class OtherItemsEnumerator:IEnumerator<OtherItem>{
....
}
public static ItemsEnumerator GetOtherItemsEnumerator() {
return new ItemsOtherEnumerator();
}
}
this way i could do :
foreach(var item in AllItems.GetItemsEnumerator()){
//do something with item
}
which won't work, because according to c# spec ItemsEnumerator doesn't have a GetEnumerator function(To be used in a foreach statement)
If I change it to this
public static class AllItems {
public sealed class ItemsEnumerator: IEnumerator{
.....
public IEnumerator<Item> GetEnumerator() {
return this;
}
}
public static ItemsEnumerator GetItemsEnumerator() {
return new ItemsEnumerator();
}
}
Is this a good design in general, or am I missing something here?
EDIT: Clarification on c# spec limitation
I am trying to make a class-library with a factory class that provides enumerators for different items via method calls. Note: Those items don't exist in a collection and can only be created knowing the previous one. (e.g. x(i) = x(i-1) + θ) Because of that I cannot implement those items as IEnumerable(s)
You don't need to go to that level of detail - you can just use yield to achieve a "conceptual" collection without having to wire in all of the enumeration plumbing:
public IEnumerable<Item> GetItems()
{
int i = 0;
while(i < 100) // or foreach(Item item in _baseItems), etc.
{
Item item = new Item();
item.X = i;
i += 10;
yield return item;
}
}
Note that this is just for illustration to show one way of returning a "collection" of items that are generated on-the fly. You are free to adapt this to your situation in whatever way is appropriate.
Here it goes my question:
I intend to create several lists of objects, being each of the objects from the same class.
However, within each of the lists, I would like the different instances of the objects to share a common member I could change from any of these instances.
Of course, each of the lists have its own "static" member.
I hope I had explained myself, I am beginner and I am not sure whether my question has an obvious solution.
Edit:
I am working on an existing code, and I make every step by doing a trial-error approach. I do not know exactly how to explain it better: I have List list1, and List list2. The set of instances within list1 will have members with different values, but I want to have a member in class A which can be modified from any instance within the list1 and to be common to all the instances in list1. Similarly for list2, but with a different "static" member that the one in list1.
I think this will roughly achieve what you are looking to do. There are many ways to change the structure of the code below to achieve different goals but basically what you will need to do is create some sort of custom list that when items are added to it, it attaches itself to those items, and removes itself from them when they are removed.
public class CustomList : IList<IItem>
{
public Object CommonMember { get; set; }
private List<IItem> _internalList = new List<IItem>();
public void Add(IItem item)
{
item.OwnedList = this;
this._internalList.Add(item);
}
public void Remove(IItem item)
{
if(this._internalList.Remove(item))
{ item.OwnedList = null; }
}
... you will need to implment more members
}
public abstract class IItem
{
public Object OwnedListCommonMember
{
get {
if(this.OwnedList != null)
{ return this.OwnedList.CommonMember; }
else { return null; }
}
}
public CustomList OwnedList { get; set; }
}
Suppose you have a class Person :
public class Person
{
public string Name { get; set;}
public IEnumerable<Role> Roles {get; set;}
}
I should obviously instantiate the Roles in the constructor.
Now, I used to do it with a List like this :
public Person()
{
Roles = new List<Role>();
}
But I discovered this static method in the System.Linq namespace
IEnumerable<T> Enumerable.Empty<T>();
From MSDN:
The Empty(TResult)() method caches an
empty sequence of type TResult. When
the object it returns is enumerated,
it yields no elements.
In some cases, this method is useful
for passing an empty sequence to a
user-defined method that takes an
IEnumerable(T). It can also be used to
generate a neutral element for methods
such as Union. See the Example section
for an example of this use of
So is it better to write the constructor like that? Do you use it? Why? or if not, Why not?
public Person()
{
Roles = Enumerable.Empty<Role>();
}
I think most postings missed the main point. Even if you use an empty array or empty list, those are objects and they are stored in memory. The Garbage Collector has to take care of them. If you are dealing with a high throughput application, it could be a noticeable impact.
Enumerable.Empty does not create an object per call thus putting less load on the GC.
If the code is in low-throughput location, then it boils down to aesthetic considerations though.
I think Enumerable.Empty<T> is better because it is more explicit: your code clearly indicates your intentions. It might also be a bit more efficient, but that's only a secondary advantage.
On the performance front, let's see how Enumerable.Empty<T> is implemented.
It returns EmptyEnumerable<T>.Instance, which is defined as:
internal class EmptyEnumerable<T>
{
public static readonly T[] Instance = new T[0];
}
Static fields on generic types are allocated per generic type parameter. This means that the runtime can lazily create these empty arrays only for the types user code needs, and reuse the instances as many times as needed without adding any pressure on the garbage collector.
To wit:
Debug.Assert(ReferenceEquals(Enumerable.Empty<int>(), Enumerable.Empty<int>()));
Assuming you actually want to populate the Roles property somehow, then encapsulate that by making it's setter private and initialising it to a new list in the constructor:
public class Person
{
public string Name { get; set; }
public IList<Role> Roles { get; private set; }
public Person()
{
Roles = new List<Role>();
}
}
If you really really want to have the public setter, leave Roles with a value of null and avoid the object allocation.
The problem with your approach is that you can't add any items to the collection - I would have a private structure like list and then expose the items as an Enumerable:
public class Person
{
private IList<Role> _roles;
public Person()
{
this._roles = new List<Role>();
}
public string Name { get; set; }
public void AddRole(Role role)
{
//implementation
}
public IEnumerable<Role> Roles
{
get { return this._roles.AsEnumerable(); }
}
}
If you intend some other class to create the list of roles (which I wouldn't recommend) then I wouldn't initialise the enumerable at all in Person.
The typical problem with exposing the private List as an IEnumerable is that the client of your class can mess with it by casting. This code would work:
var p = new Person();
List<Role> roles = p.Roles as List<Role>;
roles.Add(Role.Admin);
You can avoid this by implementing an iterator:
public IEnumerable<Role> Roles {
get {
foreach (var role in mRoles)
yield return role;
}
}