C# Private variable list - c#

I suspect this question illustrates my lack of understanding about what's going on behind the scenes in C#, but hey...
While doing a CRM SDK project in C# that involved a number of private variables (which were CRM objects called "lists", but that doesn't really matter), I found I was repeating nearly the same lines of code. I tried shoving the private variables into an array of type "list", and then looping over this array, and setting the variables one by one. Except that, of course, that didn't work, because (I think) what I'm actually working with is a copy of my list of variables.
Anyway, to cut a long story short, is there a way to set a load of private variables in a loop? Am I missing something very obvious, or is what I want to do not actually possible?

Do you actually need the variables to be separate? Can you just use a collection of some form to start with - not as a copy, but to hold the data without any separate variables?
What were you doing with these variables in the repetitive code? You may find that you can get by with a convenience method instead of really looping.

You could try reflection,
Reflection.FieldInfo fields[] = this.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

Normally you would create a Reset() method that ... resets the members of the object.

If you are using an object/class then the values in the array should be referenced, as opposed to using copies of the values.
Do you mean something like this?
private List<T> UpdateValues<T>(T[] values)
{
List<T> list = new List<T>();
foreach(T t in values)
{
list.Add(t);
}
return list;
}
Then you have a list of T's which should be fairly easy to use. If that's not it can you elaborate the problem a little?

Related

How Iterate through a list of an object with Lambda Expressions

I have an object, which inside is another object that is a list of an object.
What I am trying to do is iterate through the list and to take each a value from the list to set a label. So, if I have 5 values in my list:
for (x=0; list.count; x++)
{
lblDayOne.Text = list[x].DayOne.Value; <-I want to set this with the value relevant for Day One and so on and so forth for each label as below
lblDayTwo.Text = list[x].DayTwo.Value;
lblDayThree.Text = list[x].DayThree.Value;
lblDayFour.Text = list[x].DayFour.Value;
lblDayFive.Text = list[x].DayFive.Value;
}
Is there a way to do this? I tried with foreach but no luck. This is all C#
Call List<T>.ForEach(). Pass it a lambda.
Enumerable.Range(0,9).ToList().ForEach( n => Console.WriteLine(n) );
UPDATE
Wait a minute, are you trying to iterate not over your list of objects, but over a list of PROPERTIES in each object in the list (DayOne, DayTwo, etc.), and possibly also automagically link them up with variables with similar names? No, there's nothing like that in C#. You'd have to roll your own using reflection, and that would be a lot of work for very little payoff.
You could consider storing those values not as properties, but in a Dictionary<String,String>, or perhaps an array String DayValues[]; either of those would support iteration, but you'd still have the problem of linking up the items programmatically with the label controls. You might be able to look up the controls by name, though, depending how you're doing your UI -- ASP.NET has FindControl(string id), for example.
But what you have above is a perfectly clear, readable way of doing it, just the way it is. That's how I'd do it in production code, except that I'd assign list[x] to a local variable at the top of the loop block to clear up the visual noise a bit. An iterating lambda solution would sacrifice clarity for cleverness, not a good tradeoff in code you'll have to maintain. If it's just fun code, on the other hand, by all means stretch out and learn something new. Lambdas are a fantastic toy.
If that's really the question you're asking, you should edit your question for clarity.

Converting C# to Java, how do I handle IEnumerable?

I've been tasked with converting some C# code to Java. Most of it is fine, but I am having some trouble working out how to translate IEnumerable.
The code I have in C# is this:
public IEnumerable<Cat> Reorder(IEnumerable<Cat> catList)
{
// some logic that reorders the list
}
My googling suggested that I should be using Iterable<Cat> as an alternative. However, I also stumbled upon something saying you should never have Iterable<T> as a return type.
I'm a bit unfamiliar with data structures in Java. What should I be returning, and how would you re-order a collection of objects?
In C#, assuming you don't use linq, you'd create an empty array or List or similar, and add the items in as you repeatedly iterate through them, checking the criteria. Which data structure would I use in Java to achieve this?
It depends a bit on what you want to do with the return value.
Java has no LINQ, so using an Iterable<T> other than inside a foreach loop is a bit of a PITA. This blog post describes it in more depth.
The alternative is to return a Collection<T>.
Having said that, returning an Iterable<T> is not wrong, it just makes it harder to consume the return value in certain scenarios.
In Java you would use an implementation of List<T> like ArrayList<T> for temporary instances inside methods. When you would want to return that instance from a method, the return type would be the interface List<T> or Collection<T>.
You could do something like Collections.sort(list); if you implement a Interface Comparable at your objects (similiar can be done with c# and the IComparer)
"add the items in as you repeatedly iterate through them," I hope you don't really mean what I'm thinking you mean... There are a hell lot of sorting algorithms.
There's nothing wrong with Iterable, when you need to use it.
However, considering what the code above tells me, I think you'd be better going with java.util.Collection or java.util.List (the latter if catList is definitely a list of cats).
The way of reordering actually depends on the ordering requirements. It's probably as simple as using Collections.sort(List list)
You should identify the data structure you need.
Basically the 3 great data structure families are:
List: An ordered index-based collection;
Set: A collection that contains no duplicate elements;
Map: A key-value based collection (A dictionnary in C#). Not adapted here in this precise case.
Depending on what you need, you should return List<Cat> or Set<Cat>.

Best practice way to store collection

I am porting a C# application to C++, and I have the following class (where Box is a struct, and the BoxStore will be a global, long living object in the app):
public class BoxStore
{
private List<Box> boxes;
...
public List<Box> GetBoxes()
{
return this.boxes;
}
}
I'm planning to store the boxes collection in a std::vector in C++. There are multiple ways to define the collection:
std::vector<Box> boxes;
shared_ptr<std::vector<Box>> boxes;
std::vector<Box>& boxes;
(*std::vector<Box> boxes;)
What is - if there is any - best way to go? I guess the last option (to store a raw pointer to the collection) is the worst solution without any benefit (hence the parantheses)).
And what is the best approach to port the GetBoxes method? Of course this depends on the way of storing the collection. I can see multiple approaches here too:
(std::vector<Box> GetBoxes();)
std::shared_ptr<std::vector<Box>> GetBoxes();
*std::vector<Box> GetBoxes();
std::vector<Box>& GetBoxes();
The first solution seems incorrect, because the vector would get copied upon return, thus the caller couldn't modify the original collection.
However the other three approaches seem equally good to me. The BoxStore instance is long living, and is not getting destroyed while the app is running, so the caller won't have ownership over the collection. Does this mean, that returning a shared_ptr is semantically incorrect? (It is always the BoxStore object, who frees the collection.)
And is there a significant difference between returning a raw pointer or a reference?
This could be the possible one you are looking for.
BoxStore really owns the objects. So, no pointers etc are needed.
I'm assuming that the individual box objects and the list won't outlive the Store.
If you have that requirement, then you might need to consider using pointers.
Regarding the return by reference is not really good design since it violates the encapsulation. So, if you didn't have the constraint to allow the clients to modify the list, I would have provided a copy of the list to out.
#include <list>
class Box
{
...
};
class BoxStore
{
private :
std::list<Box> boxes;
public :
std::list<Box>& GetBoxes()
{
return boxes;
}
}

Avoiding array duplication

According to [MSDN: Array usage guidelines](http://msdn.microsoft.com/en-us/library/k2604h5s(VS.71).aspx):
Array Valued Properties
You should use collections to avoid code inefficiencies. In the following code example, each call to the myObj property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop.
[Visual Basic]
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
DoSomething(obj.myObj(i))
Next i
[C#]
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
Other than the change from myObj[] to ICollection myObj, what else would you recommend? Just realized that my current app is leaking memory :(
Thanks;
EDIT: Would forcing C# to pass references w/ ref (safety aside) improve performance and/or memory usage?
No, it isn't leaking memory - it is just making the garbage collector work harder than it might. Actually, the MSDN article is slightly misleading: if the property created a new collection every time it was called, it would be just as bad (memory wise) as with an array. Perhaps worse, due to the usual over-sizing of most collection implementations.
If you know a method/property does work, you can always minimise the number of calls:
var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
DoSomething(arr[i]);
}
or even easier, use foreach:
foreach(var value in obj.myObj) {
DoSomething(value);
}
Both approaches only call the property once. The second is clearer IMO.
Other thoughts; name it a method! i.e. obj.SomeMethod() - this sets expectation that it does work, and avoids the undesirable obj.Foo != obj.Foo (which would be the case for arrays).
Finally, Eric Lippert has a good article on this subject.
Just as a hint for those who haven't use the ReadOnlyCollection mentioned in some of the answers:
[C#]
class XY
{
private X[] array;
public ReadOnlyCollection<X> myObj
{
get
{
return Array.AsReadOnly(array);
}
}
}
Hope this might help.
Whenever I have properties that are costly (like recreating a collection on call) I either document the property, stating that each call incurs a cost, or I cache the value as a private field. Property getters that are costly, should be written as methods.
Generally, I try to expose collections as IEnumerable rather than arrays, forcing the consumer to use foreach (or an enumerator).
It will not make copies of the array unless you make it do so. However, simply passing the reference to an array privately owned by an object has some nasty side-effects. Whoever receives the reference is basically free to do whatever he likes with the array, including altering the contents in ways that cannot be controlled by its owner.
One way of preventing unauthorized meddling with the array is to return a copy of the contents. Another (slightly better) is to return a read-only collection.
Still, before doing any of these things you should ask yourself if you are about to give away too much information. In some cases (actually, quite often) it is even better to keep the array private and instead let provide methods that operate on the object owning it.
myobj will not create new item unless you explicitly create one. so to make better memory usage I recommend to use private collection (List or any) and expose indexer which will return the specified value from the private collection

Hopefully simple question about modifying dictionaries in C#

I have a huge dictionary of blank values in a variable called current like so:
struct movieuser {blah blah blah}
Dictionary<movieuser, float> questions = new Dictionary<movieuser, float>();
So I am looping through this dictionary and need to fill in the "answers", like so:
for(var k = questions.Keys.GetEnumerator();k.MoveNext(); )
{
questions[k.Current] = retrieveGuess(k.Current.userID, k.Current.movieID);
}
Now, this doesn't work, because I get an InvalidOperationException from trying to modify the dictionary I am looping through. However, you can see that the code should work fine - since I am not adding or deleting any values, just modifying the value. I understand, however, why it is afraid of my attempting this.
What is the preferred way of doing this? I can't figure out a way to loop through a dictionary WITHOUT using iterators.
I don't really want to create a copy of the whole array, since it is a lot of data and will eat up my ram like its still Thanksgiving.
Thanks,
Dave
Matt's answer, getting the keys first, separately is the right way to go. Yes, there'll be some redundancy - but it will work. I'd take a working program which is easy to debug and maintain over an efficient program which either won't work or is hard to maintain any day.
Don't forget that if you make MovieUser a reference type, the array will only be the size of as many references as you've got users - that's pretty small. A million users will only take up 4MB or 8MB on x64. How many users have you really got?
Your code should therefore be something like:
IEnumerable<MovieUser> users = RetrieveUsers();
IDictionary<MovieUser, float> questions = new Dictionary<MovieUser, float>();
foreach (MovieUser user in users)
{
questions[user] = RetrieveGuess(user);
}
If you're using .NET 3.5 (and can therefore use LINQ), it's even easier:
IDictionary<MovieUser, float> questions =
RetrieveUsers.ToDictionary(user => user, user => RetrieveGuess(user));
Note that if RetrieveUsers() can stream the list of users from its source (e.g. a file) then it will be efficient anyway, as you never need to know about more than one of them at a time while you're populating the dictionary.
A few comments on the rest of your code:
Code conventions matter. Capitalise the names of your types and methods to fit in with other .NET code.
You're not calling Dispose on the IEnumerator<T> produced by the call to GetEnumerator. If you just use foreach your code will be simpler and safer.
MovieUser should almost certainly be a class. Do you have a genuinely good reason for making it a struct?
Is there any reason you can't just populate the dictionary with both keys and values at the same time?
foreach(var key in someListOfKeys)
{
questions.Add(key, retrieveGuess(key.userID, key.movieID);
}
store the dictionary keys in a temporary collection then loop over the temp collection and use the key value as your indexer parameter. This should get you around the exception.

Categories

Resources