Variable storing in Class File - c#

I have a list view in the Panorama item, i would like to redirect to a new page to display more details about the item i have selected. May i know how do i do about this?
My current idea is to , When clicked , it will store the variable into the class file and my the other form when loaded it will always extract from that class file variable and search from the list.
I'm planning to keep a list of array, do i keep it in the class file so that it is accessible to all? If so , how do i do that too?

It looks like you could use up a lot of memory for transient data. Have you considered just calling Navigate() to load your new page and passing the instantiating data as post data - like here. This way you only create the new page with the data needed and don't hog memory.

I would personally use a RingBuffer for this... http://en.wikipedia.org/wiki/Circular_buffer
And I would have the indexer return the Image associated with the index. I would additionally have the TotalFrames present and returned via the Length of the List entries or similar. (Even if past the bounds of the list by using modulo)
I would also have a float indexer which would operate on values such as 25.7 or a string operator which took Degrees form.
I would also overload the operators to allow for rotation based on these methods accordingly. (For sliding and gestures inter alia)
You would then have a single enumerator with two operating styles, a repeating and a non repeating for going through the frames (including in reverse)
And this was just off the top... don't make me do an example :p

Related

Safeguarding against user error when saving a list of information

I have a private List<Experience> experiences; that tracks generic experiences and experience specific information. I am using Json Serialize and Deserialize to save and load my list. When you start the application the List populates itself with the current saved information automatically and when a new experience is added to the list it saves the new list to file.
A concern that is popping into my head that I would like to get ahead of is, there is nothing that would stop the user from at any point doing something like experiences = new List<Experience>(); and then adding new experiences to it. Saving this would result in a loss of all previous data as right now the file is overwritten with each save. In an ideal world, this wouldn't happen, but I would like to figure out how to better structure my code to guard against it. Essentially I want to disallow removing items from the List or setting the list to a new list after the list has already been populated from load.
I have toyed with the idea of just appending the newest addition to the file, but I also want to cover the case where you change properties of an existing item in the List, and given that the list will never be all that large of a file, I thought overwriting would be the simplest approach as the cost isn't a concern.
Any help in figuring out the best approach is greatly appreciated.
Edit* Looked into the repository pattern https://www.infoworld.com/article/3107186/application-development/how-to-implement-the-repository-design-pattern-in-c.html and this seems like a potential approach.
I'm making an assumption that your user in this case is a code-level consumer of your API and that they'll be using the results inside the same memory stack, which is making you concerned about reference mutation.
In this situation, I'd return a copy of the list rather than the list itself on read-operations, and on writes allow only add and remove as maccettura recommends in the comments. You could keep the references to the items in the list intact if you want the consumer to be able to mutate them, but I'd think carefully about whether that's appropriate for your use case and consider instead requiring the consumer to call an update function (which could be the same as your add function a-la HTTP PUT).
Sometimes when you want to highlight that your collection should not be modified, exposing it as an IEnumerable except List may be enough, but in case you are writing some serious API, something like repository pattern seems to, be a good solution.

pass variables as array specflow c#

I am attempting to use Specflow to automate web tests using Selenium. So far, things are going mostly fine, but I am now running into a problem. One of my steps allow for a user to input a variable, the step looks like this:
Given I click the (VARIABLE) Menu
And the code behind it is fairly simple, just clicking on a link based on the text that is passed:
driver.FindElement(By.XPath("Xpath to get to the variable")).Click();
However, there is a later step that must use this information. That is fine, you can use "ScenarioContext.Current.Add(string, variable)" and I know about that and have been using it. It functions for the needs that I was first informed of.
My problem is that now the business wants to be able to add multiple items at the same time. This presents two problems. Attempting to just call the step a second time throws an exception: "An item with the same key has already been added." and if I put this into a Scenario Outline, which would allow me to call the variable a second time in a second run, I cannot use the first variable in the final step.
Logically, this means that passing in a variable multiple times is the problem (which makes sense, given it's passing in as a string) and so passing the variable in as an array seems the logical way to go. The idea is that when I pass the parameter from one step to another as an array instead of as a string I theoretically won't run into this error and then I will be able to iterate through the items in the array in that later step with a for loop. This seems like something that SpecFlow should be able to do, but I am having issues finding out just how to achieve this. Does anyone have an idea on how to do this? I attempted to merely use:
Scenario.Context.Current.Add(string, variable).ToArray();
However, that does not work, and all of the examples of "ToArray" I can find in the SpecFlow documentation doesn't seem to be actually changing the variables you pass from one step to another into an array, it seems to be used solely inside of individual steps and never passed between steps. Is passing parameters using ScenarioContext.Current.Add(string, variable) as an array possible in SpecFlow?
Thanks in advance.
the simplest solution to your problem is to add an array (or list) to the context in the first step and then to get it out and add to it and then replace it again in future steps:
List<string> list = new List<String>();
list.Add(variable)
ScenarioContext.Current.Add(name, list);
then later
List<String> currentList = (List<String>) ScenarioContext.Current[string];
currentList.Add(variable);
ScenarioContext.Current[name]=list;
However I feel duty bound to point out some issues with your current solution. You should investigate the PageObject pattern and hide your element selection XPath inside your page objects. Imagine the business decides to change the element that information is stored in. Now you have to change every test that does this:
driver.FindElement(By.XPath("Xpath to get to the variable")).Click();
for that variable. Using the page object pattern this is hidden inside the page object and you would only have a single place to change.
I personally would also consider sharing data using context injection as I find this allows strong typing of the data (so no cast is required like in the example above) and it allows you to know what data is stored, its not just a random bag of stuff).

Is there a LinkedList collection that supports dictionary type operations

I was recently profiling an application trying to work out why certain operations were extremely slow. One of the classes in my application is a collection based on LinkedList. Here's a basic outline, showing just a couple of methods and some fluff removed:
public class LinkInfoCollection : PropertyNotificationObject, IEnumerable<LinkInfo>
{
private LinkedList<LinkInfo> _items;
public LinkInfoCollection()
{
_items = new LinkedList<LinkInfo>();
}
public void Add(LinkInfo item)
{
_items.AddLast(item);
}
public LinkInfo this[Guid id]
{ get { return _items.SingleOrDefault(i => i.Id == id); } }
}
The collection is used to store hyperlinks (represented by the LinkInfo class) in a single list. However, each hyperlink also has a list of hyperlinks which point to it, and a list of hyperlinks which it points to. Basically, it's a navigation map of a website. As this means you can having infinite recursion when links go back to each other, I implemented this as a linked list - as I understand it, it means for every hyperlink, no matter how many times it is referenced by another hyperlink, there is only ever one copy of the object.
The ID property in the above example is a GUID.
With that long winded description out the way, my problem is simple - according to the profiler, when constructing this map for a fairly small website, the indexer referred to above is called no less than 27906 times. Which is an extraordinary amount. I still need to work out if it's really necessary to be called that many times, but at the same time, I would like to know if there's a more efficient way of doing the indexer as this is the primary bottleneck identified by the profiler (also assuming it isn't lying!). I still needed the linked list behaviour as I certainly don't want more than one copy of these hyperlinks floating around killing my memory, but I also do need to be able to access them by a unique key.
Does anyone have any advice to offer on improving the performance of this indexer. I also have another indexer which uses a URI rather than a GUID, but this is less problematic as the building incoming/outgoing links is done by GUID.
Thanks;
Richard Moss
You should use a Dictionary<Guid, LinkInfo>.
You don't need to use LinkedList in order to have only one copy of each LinkInfo in memory. Remember that LinkInfo is a managed reference type, and so you can place it in any collection, and it'll just be a reference to the object that gets placed in the list, not a copy of the object itself.
That said, I'd implement the LinkInfo class as containing two lists of Guids: one for the things this links to, one for the things linking to this. I'd have just one Dictionary<Guid, LinkInfo> to store all the links. Dictionary is a very fast lookup, I think that'll help with your performance.
The fact that this[] is getting called 27,000 times doesn't seem like a big deal to me, but what's making it show up in your profiler is probably the SingleOrDefault call on the LinkedList. Linked lists are best for situations where you need fast insertions & removals, particularly in the middle of the list. For quick lookups, which is probably more important here, let the Dictionary do its work with hash tables.

List.Add(this) inside of a class

I created a class awhile back. I used List.Add(this) inside of the class so I could access the controls I created later. It seemed to be very useful and I do not know how to create controls (more than one in the same parent control without a predefined limit) and access them later.
I was looking for Add(this) on the internet and couldn't find anymore information on it.
Is this a large resource hog or ineffective? Why can't I find more information on it? It seems very useful.
public class GlobalData
{
private static List<Member> _Members;
public partial class ChildrenPanel
{
private static List<ChildrenPanel> _ListCP = new List<ChildrenPanel>();
//X and Y position Panel | Container is the control recieving the Control
public void CreatePanel(int X, int Y, Panel Container)
{
//
// pnlStudent
//
_pnlStudent.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
_pnlStudent.Controls.Add(_lblCLastName);
_pnlStudent.Controls.Add(_lblCFirstName);
_pnlStudent.Controls.Add(_lblGrade);
_pnlStudent.Controls.Add(_lblSelected);
_pnlStudent.Controls.Add(_lblSeason);
_pnlStudent.Controls.Add(_lblAvailable);
_pnlStudent.Controls.Add(_lblGender);
_pnlStudent.Controls.Add(_ddlGrade);
_pnlStudent.Controls.Add(_ddlSelectedSports);
_pnlStudent.Controls.Add(_ddlAvailableSports);
_pnlStudent.Controls.Add(_ddlSeason);
_pnlStudent.Controls.Add(_rdbFemale);
_pnlStudent.Controls.Add(_rdbMale);
_pnlStudent.Controls.Add(_btnRemoveChild);
_pnlStudent.Controls.Add(_btnRemoveSport);
_pnlStudent.Controls.Add(_btnAddSport);
_pnlStudent.Controls.Add(_txtCLastName);
_pnlStudent.Controls.Add(_txtCFirstName);
_pnlStudent.Location = new System.Drawing.Point(X, Y);
_pnlStudent.Name = "pnlStudent";
_pnlStudent.Size = new System.Drawing.Size(494, 105);
//Still playing with the tab index
_pnlStudent.TabIndex = 10;
// Adds controls to selected forms panel
Container.Controls.Add(_pnlStudent);
// Creates a list of created panels inside the class
ListCP.Add(this);
}
Just make sure that you Remove the instance again when it's no longer needed, otherwise the List holding a reference to it will keep it in memory forever (Welcome to memory leaks in .NET after all).
I may revise this answer once I see some code, but my initial response is that it is not a resource hog. As to whether it is effective or not, some example code will be required.
Adding an object to a collection does not take up a large amount of resources because you are simply adding a reference to the object into the collection. You still only have a single object, but two (or more) variables that point to that object, so the only extra resources you are using are the minimal memory used by the references.
If your List is static or otherwise globally available, then you're doing something very bad.
ASP.Net is structured such that every request to your page - including postbacks - from every user results in a new instance of the page class. that's a lot of page instances. If references to all these instances are saved somewhere, the instances can never be garbage collected. You've created something analogous to a memory leak and you'll quickly find yourself running out of resources after you deploy to production.
The really dangerous thing here is that if you only do functional testing and no load testing the problem will likely not show up during your tests at all, because it will work fine for a few hundred (maybe even thousand) requests before blowing up on you.
If you're worried about dynamic controls, there are several better ways to handle this:
Put a fixed limit on the maximum number of controls you will allow, and add all of them to the page up front. Then only show/render them (toggled via the .Visible property) as you need them.
Make it data-driven. Rather than dynamically add a control, insert something to a database table and then bind a query on that table to a repeater or other data control (my preferred method).
Just make sure you're recreating every dynamic control you need at the right place (Pre-Init) in the page lifecycle.

Hashing the state of a complex object in .NET

Some background information:
I am working on a C#/WPF application, which basically is about creating, editing, saving and loading some data model.
The data model contains of a hierarchy of various objects. There is a "root" object of class A, which has a list of objects of class B, which each has a list of objects of class C, etc. Around 30 classes involved in total.
Now my problem is that I want to prompt the user with the usual "you have unsaved changes, save?" dialog, if he tries to exit the program. But how do I know if the data in current loaded model is actually changed?
There is of course ways to solve this, like e.g. reloading the model from file and compare against the one in memory value by value or make every UI control set a flag indicating the model has been changed. Now instead, I want to create a hash value based on the model state on load and generate a new value when the user tries to exit, and compare those two.
Now the question:
So inspired of that, I was wondering if there exist some way to generate a hash value from the (value)state of some arbitrary complex object? Preferably in a generic way, e.g. no need to apply attributes to each involved class/field.
One idea could be to use some of .NET's serialization functionality (assuming it will work out-of-the-box in this case) and apply a hash function to the content of the resulting file. However, I guess there exist some more suitable approach.
Thanks in advance.
Edit:
Point taken about the hashing and possible collisions. Instead, I am going for deep comparing value by value. I am already using the XML serializer for persistence, so I am just going to serialize and compare chars. Not pretty, but it does the trick in this case.
Ok you can use reflection and some sort of recursive function of course.
But keep in mind that every object is a model of a particular thing. I mean there maybe a lot of "unimportant" fields and properties.
And, thanks to #compie!
You can create a hash function just for your domain. But this requires strong mathematic skills.
And you can try to use classic hash functions like SHA. Just assume that your object is a string or byte array.
Because this is a WPF app, it may be easier than you think to be notified of changes as they happen. The event architecture of WPF allows you to create event handlers at a level somewhere above where the event actually originates. So, you could create event handlers for the various "change" events of your UI elements in the root window of your interface and set the "changed" flag at that scope.
WPF Routed Events Overview
I would advice against this. Different objects can have the same hash. It's not safe to rely on this for checking if changes have to be saved.

Categories