I'm very new with c#, and was previously attempting to ignore classes and build my small program structurally more similar to PHP. After reaching a road block, I'm trying to start over and approach the problem properly OO. I'm taking a long file, and in a loop, every time certain conditions are met, I want to make a new object. How can I have it create a new object, without having to specify a unique name?
Referral ObjectName = new Referral(string, string, int);
Secondly, once this is done, and the strings & int set their appropriate object properties, how can i unique-ify the class by one property, and then sort the class by another?
I'm sorry if these are basic questions, I have spent a large, large amount of time first trying to figure it out on my own with google, and a textbook. If only C# would allow multi-dimensional arrays with different types!
Thank you so much!
PS. I do mean to extract a list of unique objects.
All these answers, while helpful, seem to involve creating a shadow set of IEnumerables. Is there no way to do this with the class itself?
Trying the first solution, provided by Earwicker, adding each object to a List from within the loop, when I try to Write a property of the element to the console, i get the ClassName+Referral. What could I be doing wrong?--solved. still needed .property
still working. . .
C# does allow untyped arrays. All objects are derived ultimately from object, so you use an array or container of objects. But it's rarely necessary. How many types of object do you have?
Within the loop block, you can create an object exactly as you do in that line of code (except with the syntax fixed), and it will be a new object each time around the loop. To keep all the objects available outside the loop, you would add it to a container:
List<Referral> referrals = new List<Referral>();
// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals.Add(r);
Suppose Referral has a numeric property called Cost.
referrals.Sort((l, r) => l.Cost - r.Cost);
That sorts by the cost.
For ensuring uniqueness by some key, you may find it easier to pick a more suitable container.
Dictionary<string, Referral> referrals = new List<Referral>();
// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals[str1] = r;
This stores the referral in a "slot" named after the value of str1. Duplicates will overwrite each other silently.
First, you're going to need to spend some time familiarizing yourself with the basics of the language to be productive. I recommend you take a little time to read up on C# before getting in too deep - otherwise you'll spend a lot of your time spinning your wheels - or reinventing them :)
But here's some info to get you started.
Typically, in C# you create classes to represent elements of your program - including those that are used to represent information (data) that your program intends to manipulate. You should really consider using one, as it will make data manipulation clearer and more manageable. I would advise avoiding untyped, multi-dimensions array structures as some may suggest, as these rapidly become very difficult to work with.
You can easily create a Referall class in C# using automatic properties and a simple constructor:
public class Referall
{
// these should be named in line with what they represent...
public string FirstString { get; set; }
public string AnotherString { get; set; }
public int SomeValue { get; set; }
public Referall( string first, string another, int value )
{
FirstString = first;
AnotherString = another;
SomeValue = value;
}
}
You can add these to a dictionary as you create them - the dictionary can be keyed by which ever property is unique. Dictionaries allow you to store objects based on a unique key:
Dictionary<string,Referall> dict = new Dictionary<string,Referall>();
As you process items, you can add them to the dictionary:
Referall ref = new Referall( v1, v2, v3 );
// add to the dictionary, keying on FirstString...
dict.Add( ref.FirstString, ref );
If you need to sort items in the dictionary when you're done, you can use LINQ in C# 3.0:
IEnumerable<Referall> sortedResults =
dict.Values.OrderBy( x => x.AnotherString );
You can sort by multiple dimension using ThenBy() as well:
IEnumerable<Referall> sortedResults =
dict.Values.OrderBy( x => x.AnotherString )
.ThenBy( x => x.SomeValue );
List<Referral> referrals = new List<Referral>();
for (...)
{
referrals.Add(new Referral(string1, string2, number1));
}
Then, if you're using Linq (which I highly suggest), you can do this:
IEnumerable<Referral> sorted = referrals.OrderBy(x => x.string1).ThenBy(x => x.string2);
Otherwise, you can use the Sort() method on List<Referral>.
You can create an object without a reference, but you won't have any access to it later:
new Referral(string, string, int);
If you wish to put them in an array/list, these different types need to have a common base class. This is called polimorfism, which is a very important concept in OO programming.
You cannot ignore classes while using c#. Don't resist the change!
Do you really not need to create a class here? Do you really not need to give it a name? C# does allow loose typing, but type safety is a good thing.
I don't fully understand what you're trying to do. But maybe LINQ is what you're looking for. There's tons of documentation around, but as a quick 'teaser' have a look at the 101 Linq samples on MSDN
C# includes a wonderful feature called "iterator blocks". What you want to do is use the yield keyword to create an Enumerable of your Referal object, something like this (not that I'm making the file format and property names up, because you didn't share that):
public class Referral
{
public Guid id { get; private set; } // "uniquify"
public int ReferringId { get; set; }
public string ReferrerText { get; set; }
public string ReferrerDescription { get; set; }
private Referral()
{
id = new Guid();
}
private Referral(string Text, string Description, int ReferringId) : this()
{
this.ReferrerText = Text;
this.ReferrerDescription = Description;
this.ReferringId = ReferringId;
}
public static IEnumerable<Referral> GetReferrals(string fileName)
{
using (var rdr = new StreamReader(fileName))
{
var next = new Referrer();
int state = 0;
string line;
while ( (line = rdr.ReadLine() ) != null)
{
switch (state)
{
case 0:
next.ReferrerText = line;
state = 1;
break;
case 1:
next.ReferrerDescription = line;
state = 2;
break;
case 2:
next.ReferringId = int.Parse(line);
yield return next;
next = new Referral();
state = 0;
break;
}
}
}
}
}
Now you want to sort the referrals and presumable enumerate over them for some purpose. You can do that easily like this:
foreach (var referral in Referral.GetReferrals(#"C:\referralfile.txt").OrderBy( r => r.Text ) )
{
OutputReferral(referral);
}
Related
UPDATE
Obviously, the original question was confusing so I'll try to simplify it.
I'm working with a complex algorithme that is providing a list of object (let's say a company).
For each of those company I will have to load a large amount of data (let's say a list of employee).
public class Company
{
public string Name { get; set; } = "";
public List<Employee> EmployeeList { get; set; } = new List<Employee>();
}
public class Employee
{
public string FirstName { get; set; } = "Random first name";
public string LastName { get; set; } = "Random last name";
}
public MemoryTest()
{
//Simulate the complex algorithme...
//I can't change how I get that list and my question ain't about this part.
List<Company> companyList = new List<Company>();
for (int i = 0; i < 50000; i++)
{
companyList.Add(new Company() { Name = "Random company name " + i });
}
//Simulate the details loading. This is where the memory gets filled
foreach (Company company in companyList)
{
company.EmployeeList.AddRange(new Employee[25000]);
//Do some calculation and save to DB...
}
}
The problem with this code is that the memory allocated during each iteration won't be released until the end of the loop.
After reading this article I had hopes that the JIT would be able to determine a company reference would not be used after an iteration since the companyList isn't use beyond the foreach:
In release builds, the JIT is able to look at the program structure to work out the last point
within the execution that a variable can be used by the method and will discard it when it is
no longer required.
... but sadly, the JIT doesn't extrapolate that far.
In order to use a few memory as possible, my question is the following: Is there a way the loop thru a collection AND to remove reference to the element between each iteration?
Here's a more generic example if you don't want to work with Company / Employee
Dictionary<int, List<string>> dict = new Dictionary<int, List<string>>();
for (int i = 0; i < 100000; i++)
{
dict.Add(i, new List<string>());
}
foreach (var item in dict)
{
item.Value.AddRange(new string[25000]);
}
I'm going to revise me original answer here. Not to beat the proverbial dead horse but I just want to emphasize that if you're having to pop items out of a collection to keep the collection from rooting the objects in memory then it's almost certain you've got some issues with the design of the your application. There might be some scenarios where that's a great design but I say most often it's not.
Lets take Smurf's company scenario and change it slightly to make it not hold onto large objects in the collection at all.
I'm going to ignore the dictionary of Company objects. It's never used as a dictionary and is only used as a collection. It's also important to note that what's in the dictionary to begin with is not a complete company object. We had to use the original company object to retrieve the extra data. We usually call that a key. So instead of that dictionary, we'll have a stream of keys instead. Here's the key objects:
public class CompanyKey
{ }
And a data source to produce keys. This might actually be Smurfs dictionary, but for our purposes we'll make it an iterator method. That way nothing is rooting these things in memory. If the keys are small then it doesn't really matter but better to not use a collection if you don't need it.
public class CompanyKeySource
{
public IEnumerable<CompanyKey> GetKeys()
{
for(int i =0;i < 10;++i)
yield return new CompanyKey();
}
}
And here's the actual company object:
public class Company
{
public EmployeeData Employees { get; set; }
}
And the big glob of data. That's in the employee object.
public class Employee
{
public string[] LotOfData { get; set; }
}
Finally we need something that'll load the big glob of data into the company object. That's usually a repository of some type:
public class CompanyDataRepository
{
public IEnumerable<Company> GetCompanyDetails(IEnumerable<CompanyKey> keys)
{
foreach (var key in keys)
{
yield return new Company() { Employees = GetEmployees(key) };
}
}
public EmployeeData GetEmployees(CompanyKey key) =>
new EmployeeData() { LotOfData = new string[2500] };
}
Now we wire everything together and iterate over our company instances.
static void Main(string[] _)
{
CompanyDataRepository repository = new CompanyDataRepository();
CompanyKeySource keySource = new CompanyKeySource();
var keys = keySource.GetKeys();
foreach (var company in repository.GetCompanyDetails(keys))
{
// do whatever it is you're doing with your companies...
}
}
Now there's no need to pop items off a dictionary to keep them out of memory. The large chunks of data are used where they're needed and then can be eligible for collection right away.
foreach is using an enumerator concept. With the help of .MoveNext() method, it is observing items in the collection one after another with the help of .Current property. In other words, your code is translated to something like:
List<Compagny>.Enumerator enumerator = new List<Compagny>().GetEnumerator();
try
{
while (enumerator.MoveNext())
{
Compagny current = enumerator.Current;
LoadContacts(current);
current.Log = "Very large string...";
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
As you see, each var compagny is in the end just a single local variable of reference type. This reference is being replaced in every iteration. So, from this point of view, current variable becomes an additional root for some Compagny object, for the time of the iteration.
The difference here may be what's the range of such a root. In case of the Debug build, it is indeed the whole {} block of a underlying while loop (in fact, the whole method, from the CIL perspective). In case of Release build, JIT is reporting roots more aggresively. So, it will report current as no longer needed, as fast as it is indeed no longer needed. In you case, you are using current till the end of the {} so it is the same.
The difference could be seen if you don't use compagny till the end of the block, like:
foreach (var compagny in compagnyList)
{
this.LoadContacts(compagny);
this.LoadNotes(compagny.ContactList)
compagny.Log = "Very large string...";
CallingHereLongLastingMethod(); // Debug - compagny is still a root
// Release - compagny is no longer a root
}
BUT... all this does not matter because current is just an additional object root. Object itself ("compagny") is still rooted by the compagnyList itself.
"would the GC be smart enough to understand that the company object would not be reused beyond the foreach iteration and mark it as candidate for garbage collection (despite the compagnyList that would remain be on the stack)?" question suggests you have some problems in understanding reference types and the GC fundamentals. List<> is a reference type, it contains of the reference (living "on the stack" as a local variable) and the data - collection of the companies.
Based on MikeJ's answer, I created a generic method that will loop thru a list and remove the reference to the element right after the iteration:
public static IEnumerable<T> PopEnumerable<T>(this List<T> list)
{
while (list.Count > 0)
{
yield return list[0];
list.RemoveAt(0);
}
}
That way you can still call the foreach loop...
foreach (Company company in companyList.PopEnumerable())
{
company.EmployeeList.AddRange(new Employee[25000]);
}
... but only the company of the current iteration will remain in memory. I did some benchmark and the memory allocation that use to reach 16 gb dropped to less than 100 mb for the whole process.
I'm trying to store information in a block of anonymous values
//holds all info
var jobs = new { newJob, numBytes, requiredTime };
then take that information and place it into a list as a single element
//puts above info into a list
joblist.Add(Convert.ToString(jobs));
Console.WriteLine(joblist[0]); //testing purposes
now what I would like to do is be able to call joblist and take the value of example numBytes at position 4.
Is this possible? Or could someone help with an alternate way of doing this? Much thanks!
Create a named class. Then you can have a list of objects of that type and manipulate that list in any way you want.
Using classes is best-practice for what you are trying to do. By default you should consider storing structured data in an object model consisting of custom classes. There is another answer here which is proposing to use dynamic - this is valid and has its place, but it is more of a last resort solution. What you want is to play to the strength of C# which are rich classes and static typing. Anonymous types are also statically typed, but as you cannot name the type you cannot declare a statically typed list to hold them. You also can't use them as return types of methods.
The "normal" thing to do in C# would be to create a class to hold the information that you want to store. For example:
public class Job
{
public string Name { get; set; }
public int NumBytes { get; set; }
public DateTime RequiredTime { get; set; }
}
Then you can add these to a list:
var jobs = new List<Job>();
var aJob = new Job();
aJob.Name = "Job 1";
aJob.NumBytes = 123;
jobs.add(aJob);
Then you can access jobs by its index in the list:
var jobNumBytes = jobs[3].NumBytes;
One thing to note about C#, when you do:
new { newJob, numBytes, requiredTime };
The compiler, at build time, just creates you a strongly typed class (just like the Job class I created above) and generates a random name for it. It infers the property names and types from the variables that you are assigning to it. The created .exe or .dll actually does contain a class definition for this type, you just can't easily get to it from other places in your code. It isn't truly "dynamic". So using that syntax is usually just a lazy way of declaring a class that you just need for a moment. Usually just inside 1 method, then you don't need it any more. Creating a named class is usually what you want to do.
Actually I don't know exactly what you mean with "now what I would like to do is be able to call joblist and remove for example numBytes at position 4."
But I guess you just want to put the objects in a list and query for numBytes and maybe remove some elements.
With dynamics you can handle dynamic objects...
var jobs = new List<dynamic>();
for (int i = 0; i < 100; i++)
{
string newJob = "Job" + i;
int numBytes = i;
TimeSpan requiredTime = new TimeSpan(0,0,i);
//holds all info
var job = new { newJob, numBytes, requiredTime };
jobs.Add(job);
}
jobs.RemoveAll(p => p.numBytes > 50);
Instead of this, I agree with the comments below your question and would create a normal class which holds the properties you need and simply put instances of that into a list. Dynamics should be used only in very rare situations, and yours doesn't sound like it is extremely special.
I have a large amount of nested foreach loops and I'm running out of variable names to use...
Could I do something like this :
//int i = 1
string "number"+i = new String("FirstElement");
I've seen some posts about this for languages such as C and javascript, but I don't know how to do it in C#.
In case you can't name variables after other variables : how could this problem otherwise be solved?
This problem could otherwise be solved by using meaningful variable names - running out of names would mean running out of concepts for what the thing is trying to achieve, which is hard to believe.
If your requirement is to work with a collection of variables, then put them in a collection; if it's to have n number of variables all strictly defined by name, then name them explicitly, and so on.
var a = new List<int>();
for(int i=0;i<100;i++)
{
a.Add(i);
}
Console.WriteLine(a[0]);
Console.WriteLine(a[1]);
etc....
This way you make list which contains 100 elements, you can access them by nameoflist[index]
A while back I asked a similar question:
Python - neat way of creating multiple objects?
Basically, if you have lots of very similar variables named things like variable_1, variable_2, etc, then thats normally a sign that you should be using an array or list of variables instead.
So instead of 10 separate string variables, create a list (or array) of strings.
The way you are doing will not work in C#. You can not create variables at run time. If you want
you have to use a list to store your variable name and value. Therefore you better create a class to hold name of the variable and value.
class Variable
{
string Name;
string Value;
}
Now create another class to hold variables
class VaraibleHolder
{
List<Variable> Variables;
VariableHolder()
{
Variables = new List<Variables>();
}
public void Add(Variable Vbl)
{
Variable vbl = Variables.SingleOrDefault(v=>v.Name == Vbl.Name);
if(vbl == null)
{
Variables.Add(vbl);
}
}
public void Remove(string VblName)
{
//this is a lamda expression.
Variable vbl = Variables.SingleOrDefault(v=>v.Name == VblName);
if(vbl != null)
{
Variables.Remove(vbl);
}
}
public Variable GetVariable(string VblName)
{
Variable vbl = Variables.SingleOrDefault(v=>v.Name == VblName);
return vbl;
}
}
So you can use Variable holder to create and store varaibles at runtime. Hope this will help you.
Taking beginning Data Structures in C# class, trying to make a searchable arraylist of a string and an int referenced together (name and number).I need to be able to search for the name, and retrieve both the name and the number it's attached to. I was told I can use an arraylist of structs, but have never used structs. Any simple explanation how, or a better way?
Thank you in advance.
You should probably be using something like a hash for this as an ArrayList of structs is a bit square peg round hole.
You declare a struct just like a calss.
public struct Foo {
public String Bar { get; set; }
public Int32 Biz { get; set; }
}
And you can make an array list of then as you would with any type
var list = new ArrayList();
list.add(object);
The other issue here is that ArrayList isn't generic, it will cast everything to Object which means you will have to cast everything back to type Foo to work with it.
var foo = (Foo)list.item(0);
You would be much better off, if you have to go the route of List instead of Hash using a generic list class like List and declaring its type;
var list = List<Foo>();
var foo = new Foo { Bar = "Hello World", Biz = 1 };
list.add(foo);
As for searching a list, I prefer to use the LINQ methods, because they are quick to code and easy to read.
var matches = list.Where( x => x.Biz > 1 );
But if you cannot do that then iteration always works
var matches = new List<Foo>();
foreach ( var foo in list ) {
if ( list.Biz > 1 ) {
matches.add(foo);
}
}
I have a class that stores data in asp.net c# application that never changes. I really don't want to put this data in the database - I would like it to stay in the application. Here is my way to store data in the application:
public class PostVoteTypeFunctions
{
private List<PostVoteType> postVotes = new List<PostVoteType>();
public PostVoteTypeFunctions()
{
PostVoteType upvote = new PostVoteType();
upvote.ID = 0;
upvote.Name = "UpVote";
upvote.PointValue = PostVotePointValue.UpVote;
postVotes.Add(upvote);
PostVoteType downvote = new PostVoteType();
downvote.ID = 1;
downvote.Name = "DownVote";
downvote.PointValue = PostVotePointValue.DownVote;
postVotes.Add(downvote);
PostVoteType selectanswer = new PostVoteType();
selectanswer.ID = 2;
selectanswer.Name = "SelectAnswer";
selectanswer.PointValue = PostVotePointValue.SelectAnswer;
postVotes.Add(selectanswer);
PostVoteType favorite = new PostVoteType();
favorite.ID = 3;
favorite.Name = "Favorite";
favorite.PointValue = PostVotePointValue.Favorite;
postVotes.Add(favorite);
PostVoteType offensive = new PostVoteType();
offensive.ID = 4;
offensive.Name = "Offensive";
offensive.PointValue = PostVotePointValue.Offensive;
postVotes.Add(offensive);
PostVoteType spam = new PostVoteType();
spam.ID = 0;
spam.Name = "Spam";
spam.PointValue = PostVotePointValue.Spam;
postVotes.Add(spam);
}
}
When the constructor is called the code above is ran. I have some functions that can query the data above too. But is this the best way to store information in asp.net? if not what would you recommend?
This is a candidate for an immutable struct that "looks like" an enumeration:
(Also, I noticed you used the same id value for two of them, so I fixed that...
You can use the following just as you would an enumeration...
PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote;
and real nice thing is that this approach requires no instance storage other than a 4-byte integer (which will be stored on stack, since it's a struct). All hard-coded values are stored in the type itself... of which only one will exist per AppDomain...
public struct PostVoteTypeFunctions
{
private int id;
private bool isDef;
private PostVoteTypeFunctions ( ) { } // private to prevent direct instantiation
private PostVoteTypeFunctions(int value) { id=value; isDef = true; }
public bool HasValue { get { return isDef; } }
public bool isNull{ get { return !isDef; } }
public string Name
{
get
{ return
id==1? "UpVote":
id==2? "DownVote":
id==3? "SelectAnswer":
id==4? "Favorite":
id==5? "Offensive":
id==6? "Spam": "UnSpecified";
}
}
public int PointValue
{
get
{ return // Why not hard code these values here as well ?
id==1? PostVotePointValue.UpVote:
id==2? PostVotePointValue.DownVote
id==3? PostVotePointValue.SelectAnswer:
id==4? PostVotePointValue.Favorite:
id==5? PostVotePointValue.Offensive:
id==6? PostVotePointValue.Spam:
0;
}
}
// Here Add additional property values as property getters
// with appropriate hardcoded return values using above pattern
// following region is the static factories that create your instances,
// .. in a way such that using them appears like using an enumeration
public static PostVoteTypeFunctions UpVote = new PostVoteTypeFunctions(1);
public static PostVoteTypeFunctions DownVote= new PostVoteTypeFunctions(2);
public static PostVoteTypeFunctions SelectAnswer= new PostVoteTypeFunctions(3);
public static PostVoteTypeFunctions Favorite= new PostVoteTypeFunctions(4);
public static PostVoteTypeFunctions Offensive= new PostVoteTypeFunctions(5);
public static PostVoteTypeFunctions Spam= new PostVoteTypeFunctions(0);
}
It is difficult to tell from the fragment of code you have posted whether you expose any of the data outside the class.
If not, then this would work. However, if not, there are several issues:
If you are exposing the List, you should only ever return a copy of it as an IEnumerable<PostVoteType> using the yield keyword.
Make sure your PostVoteType is immutable, otherwise the references can be changed and the fields used might be altered
Looking at your code, it looks like you're just trying to create a set of objects that really just put the enum PostVotePointValue into some sort of list. I.e. you already have what you need defined in just the enum itself. I would encourage you to not define the same information in two places (this data store you are asking for and the enum). This is common mistake I see people make. They create a lookup table/list, then create an enum that mirrors the rows of the table and that means they have to modify two places for any change to the list.
If PostVotePointValue isn't an enum but just some constants or if there is more info you are planning on packing in, then this isn't relevant.
Here's some examples of how to work with Enums as 'lists' from http://www.csharp-station.com/Tutorials/Lesson17.aspx
// iterate through Volume enum by name
public void ListEnumMembersByName()
{
Console.WriteLine("\n---------------------------- ");
Console.WriteLine("Volume Enum Members by Name:");
Console.WriteLine("----------------------------\n");
// get a list of member names from Volume enum,
// figure out the numeric value, and display
foreach (string volume in Enum.GetNames(typeof(Volume)))
{
Console.WriteLine("Volume Member: {0}\n Value: {1}",
volume, (byte)Enum.Parse(typeof(Volume), volume));
}
}
// iterate through Volume enum by value
public void ListEnumMembersByValue()
{
Console.WriteLine("\n----------------------------- ");
Console.WriteLine("Volume Enum Members by Value:");
Console.WriteLine("-----------------------------\n");
// get all values (numeric values) from the Volume
// enum type, figure out member name, and display
foreach (byte val in Enum.GetValues(typeof(Volume)))
{
Console.WriteLine("Volume Value: {0}\n Member: {1}",
val, Enum.GetName(typeof(Volume), val));
}
}
}
You should be able to adapt the above into an approach that will give you a list that you can use for databinding if you need it.
I am wondering why you could not just use a simple enum for this?
public enum PostVoteType
{
UpVote = 0,
DownVote = 1,
SelectAnswer = 2,
Favorite = 3,
Offensize = 4,
Spam = 5
}
"Never" is a very hard word indeed.
In your particular case you are asserting that not only is your PostVoteType data absolute and immutable, but so is the container collection. Frankly I don't believe you can know that, because you are not the business (your interpretation of requirement is imperfect) and you are not psychic (your knowledge of the future is imperfect).
I would suggest that you always store any data which cannot be expressed as an enumeration in some kind of repository. Where you expect relational and/or transactional and/or mutable needs that means a database, if you expect high read to write ratio that can be a config file (which I believe this case should be).
Edit: In terms of memory persistance I agree with others that the cache is the best place to store this, or rather in a domain object which is backed by cache.
Aside: your construction of PostVoteTypes is horrible - strongly suggest you want a refactor :)
If it doesn't change, is commonly accessed, and is the same for all users, then the .NET cache is the proper place. Have a property that yields these values. Inside, the property checks the cache for this list and returns the stored value; otherwise, it constructs it from scratch, adds to the cache, and returns the value.
This should still probably be configured in the database though, even if you cache it. I imagine that you'll need to use these value in conjunction with other data in your DB.
When you need to often access the same data, and need not to store it into the underlying database, and that this data is about the same in every situation the application may encounter, then I suggest to use caching. Caching is born from these requirements. Caching is normally the fastest way to providing data as they are always kept in memory or something similar to ease and to make the access easier by the application.
Here is a nice caching tool provided with Microsoft Enterprise Library, the Caching Application Block.
I think it is worth to take the time to learn how to use it effectively.
create a singleton class.