My situation is like this:
A "Code" field from the source tree, needs to be mapped to a "Code" field in the destination tree. The "Code" field in the destination tree has 2 parent nodes. For the destination schema to validate, the same code must not occur more than once in the scope of the 2nd parent node. Here's an image of the hiearchy:
So within the scope of "PurchaseInformation", no same "Code" may occur. A looping functoid loops on "GoodsDescription". I've tried to create an inline C# script to handle it, but it doesn't take the scope into account. See code below:
public System.Collections.Generic.List<string> duplicateList = new System.Collections.Generic.List<string>();
public bool IsDuplicate(string code)
{
if( duplicateList.Contains(code)) {
return false;
}
else {
duplicateList.Add(code);
return true;
}
}
My problem is the global List that is created. It does not reset after each loop, but I'm unsure how to implement this functionality. My question is how I can make sure no duplicate codes are mapped within the scope of the "PurchaseInformation" record in the destination tree?
Without seeing the whole process, it's difficult to give what might be the best solution...but...
Instead of trying to reset the collection (there are reasons this is difficult) you might try a list of lists instead.
Presuming SimplifiedInvoice is an ID or something, you can use a Dictionary of Lists which will track lists of unique Code values per Invoice.
Related
I'm sorry in advance for the mess you're about to read, because I'm not 100% sure what I'm searching for.
I have created an entire UI system that automatically grabs a list of properties from various scripts/components on GameObjects (Unity) and creates a fitting UI input variant for them (for example, float gets a single line, Vector3 gets 3 lines, color gets something else etc.).
What goes into UI input fields creation is a Component (that we want to look into), while individual created UI inputs store this Component and Property Name. So when input changes in one of input fields, it does SetValue on Property of a Component. Now I have also created a variant where we peak into a Class of a property and basically list Property's Properties, so the UI input stores Component, Property Name, and subProperty's Name and modifies properties as such. All this works well.
So, now I hit a brick wall with Lists. I would like to treat individual elements of a list as properties so that I could pass them into my preexisting UI scheme.
tl;dr Does List<> treat it's individual elements as Properties, Fields or does it depend on the situation? How do I get these properties, fields or their respective names from this list in order to use them with my mess of an UI system? 0 work for me means treating individual elements of List as properties.
----------------------------
EDIT----------------------------
Again I am sorry for this mess of a question. It is a mixture of confused theory and description of an existing situation that I am trying to shoehorn into my already existing project (which is a bit too over the place to be easily reduced to an example).
If anyone grasped what I was asking for, the single easiest solution was to create a property which prior to listing was equated to an element of a list.
Example looks something like this:
public List<MyCustomClass> myCustomList;
[Listable("ForEdit")]
public myCustomClass myCustomPropertyForEdit
{
get;
set;
}
And before withdrawing properties of myCustomPropertyForEdit's class (myCustomClass) I would simply do:
myCustomPropertyForEdit = myCustomList[0]; //or whatever index is in question
Then later on I would do reflection on "myCustomPropertyForEdit" instead of myCustomList. I highly doubt this will ever help anyone because it touches more onto how I built methods for listing properties into my UI, but there it is just in case.
List stores references to objects, by providing an index you get a standard object reference, which you can proceed to query using reflection (do not do it against the list itself as you will get methods of the List class, and notthing related to what the list contains)
take for example:
public Class Tree
{
public int branches;
public Tree(int branch)
{
branches=branch;
}
}
List<Tree> trees = new List<Tree>();
trees.Add(new Tree(3));
now my list has one element at index 0;
so i can do trees[0].branches;
to access the fields/props of an element in trees.
list is not an array, it holds the actual item, allowing you to reference, not just the object but also its own unique variables. as long as they are public in the class.
I'm trying to figure out what types or operations are being used in my code (the code was originally taken from my supervisor, and modified to fit my scenario. It works, but I just need to clear a few things up and I know StackOverflow is a jackpot for clearing up any doubts :) ). The idea is to use C# to read an XML file with information on name/dimensions of four walls, compile all the info in a class (or a list... or both? I have some confusion here) and Instantiate these walls in Unity3d during runtime. The Unity parts I'm good with, but I need some help understanding what my C# stuff does.
One file, Wall.cs:
public class Wall
{
public string Name { set; get; }
public float Width { set; get; }
public float Length { set; get; }
}
Similarly, the XML file has parent tag "Walls", child tag "Wall" and subchild tags of "Name", "Width", "Length".
Main file ReadWalls.cs:
public class ReadWalls : MonoBehaviour {
public static List<Wall> ListofWalls = new List<Wall>();
public static List<Wall> ReadWallsXML(){
In this function there's a bunch of stuff to load the XML, using stuff like XmlNodeList, etc. I don't really care too much about this stuff but if anyone has any further info I wouldn't mind!
Then is a foreach loop that iterates through the XML such that it analyzes one Wall at a time. Inside it:
{Wall w = new Wall();
The next nested foreach analyzes one category (name or dimensions) at a time, at the subchild tag level in relation to the XML:
foreach (//code specifying subchild tag level)
{if (XmlNodeid.Name == "Name") {w.Name = XmlNodeid.InnerText;
//Similar if statements for "Width" and "Length", with w.Width and w.Length respectively.} //end of inner foreach
ListofWalls.Add(w);} //end of outer foreach
return ListofWalls;} //end of function
void Start()
{WallsList = ReadWallsXML();
Here in the start function, I want to print all of the information into the console (name, length, width) using Debug.Log. The following works (just printing the name for simplicity):
foreach (Wall thiswall in WallsList)
{Debug.Log(thiswall.Name);}
If I try it this way, I get an error
foreach (Wall.Name thiswallsname in WallsList)
{Debug.Log(thiswallsname);}
}//end of class
Intellisense tells me "The type 'Name' does not exist in the type 'Wall''. So, what is Wall? My understanding was that we initiated it as a Class, with Properties of Name, Length, Width. To access properties, we use the dot operation (?). So why wouldn't Wall.Name access the Name property for each Wall object that was created? Also, why is the error saying Wall is a type? And one more thing, is Wall a list, class, or both? Intellisense says it's a Class (Line 2 of ReadWalls.cs) which makes sense. But where does the list aspect come into play? How are its properties related to the list?
Note that I took a significant amount of code out for (some) brevity, and also changed a few properties/names because my real code is quite lengthy. If you notice any logical or syntax errors, worry not, because the code works. The last part of this question is the most important: I just need help in analysing what the types of my variables/data are. I apologise if I've made any other mistakes, total noob here (to StackOverflow, C#, Unity and object oriented programming) if you couldn't tell already. Also thanks in advance!
Name is a property of the Wall class, not a type of its own. The type of Name is string. Also, when you attempt foreach(Wall.Name thiswallsname in WallsList) you are, if it were a correct type, asking for each item in a list of that type. By that I mean that you are telling the code that you are expecting WallsList to be a collection of the type Wall.Name when it is actually a collection of Wall instances.
If you wanted to access the Name property of each Wall in the collection you would need to do the following:
foreach(Wall wall in WallsList)
{
Debug.WriteLine(string.Format("Name: {0}", wall.Name));
}
Which you show that you already have something basically identical to that.
Wall is a class, WallsList is a List<Wall> type. Basically a collection typed so that each item in the collection is strongly typed as a Wall. It is the same as the variable you have defined above ListOfWalls. As a note on List<T>: Any class can be made into a list of itself by defining a variable as a type of List<ClassName> - for instance List<string> will give you a list of string variables, List<int> will be a list of integers, List<List<int>> will be a list of integer lists... so on and so forth.
To print the values of each of the properties you would need to list each one out within the foreach loop:
foreach(Wall wall in WallsList)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(string.Format("Name: {0}", wall.Name));
sb.AppendLine(string.Format("Width: {0}", wall.Width.ToString()));
sb.AppendLine(string.Format("Length: {0}", wall.Length.ToString()));
Debug.WriteLine(sb.ToString());
}
Of course, you could also look into reflection to dynamically retrieve a list of property names and values from the Wall class within the foreach loop, but using the above example will work just as well if you already know the property names.
Also, why is the error saying Wall is a type? And one more thing, is
Wall a list, class, or both?
Wall is a class—the words "type" and "class" here are interchangeable. WallsList, as the name would imply, is a list made up of Wall objects.
So why wouldn't Wall.Name access the Name property for each Wall
object that was created?
The foreach statement allows you a shorthand way to iterate through collections (specifically, anything that implements the IEnumerable interface). Most commonly, you'll use this with List or Array objects. But both Lists and Arrays are made up of a certain type of objects that is declared when they are created. In this example, your WallsList object is defined as List<Wall>: it's a collection of Wall objects. So when the foreach is iterating through, it only pulls out each Wall object as a whole, not the individual properties.
To access properties, we use the dot operation (?). So why wouldn't
Wall.Name access the Name property for each Wall object that was
created?
In as simple terms as I can think of, you have to create an instance of a class before you can access the properties. Declaring Wall blah = new Wall(); allocates a space in memory for that new object and then blah.Name = "hello"; sets the property. Trying to call Wall.Name = "hello"; directly results in an error because you're trying to set something that, from the computer's perspective, doesn't exist.
SHORT VERSION
What's the best way to use reflection to turn something like string prop = "part1.first_name"; into a System.Reflection.PropertyInfo, so that I can use the GetValue and SetValue functions?
LONG VERSION
I'm using ASP .NET MVC to build a questionnaire for my organization. It's very long, so it's divided into several different pages. Since it's not uncommon for us to get requests like, "Can you move this question to that page, and this other question to another page," I need to build this to be pretty flexible for a junior programmer to change.
My model is a complex class (it's got five member classes that have mostly primitive-typed properties on them).
So, I access it by doing things like Model.part1.first_name or Model.part2.birth_date.
Since the same model is used on all of the pages, but not all of the questions are on every page, I have ActionAttributes that essentially clear out all of the properties that were submitted on the form except for the ones that were displayed on that page (so someone can't inject a hidden field into the form and have the value persist to the database).
I want to make sure that I only save valid field values and don't let the user proceed to the next page until the current one is entirely OK, but I also want to save the values that are valid, even if the user isn't allowed to proceed.
To do this, I have a function that takes two instances of my model class, a reference to the ModelStateDictionary, and a string[] of field names like "part1.first_name" and "part2.birth_date". That function needs to copy all of the values listed in the string array that do not have validation errors from the first (ie, form-submitted) object into the second (ie, loaded from the db) object.
As stated above, what's the best way to use reflection to turn something like "part1.first_name" into a System.Reflection.PropertyInfo, OR, is there a better way to accomplish this?
var infoParts = prop.Split('.');
var myType = Type.GetType(infoParts[0]);
var myPropertyInfo = myType.GetProperty(infoParts[1]);
Assuming "part1" is your type. Although this is very limited and very dependent on the string being in the correct format and the type being in the current scope.
I would probably handle this differently, using data. I would keep, in the database, which step each question belongs to. To render that step, I would select the questions that match that step and have a model that contains a list of question id/question pairs. Each input would be identified by the question id when posted back. To validate, simply compare the set of question ids with the expected ids for that step. This way, to change which question goes in which step is to only change the data in the database.
If you do end up going down that road, you'll need to split the string into parts and recursively or iteratively find the property on the object at each step.
PropertyInfo property = null;
Type type = questionModel.GetType();
object value = questionModel;
object previousObj = null;
foreach (var part in questionId.Split('.'))
{
property = type.GetProperty(part);
previousObj = value;
value = property.GetValue(value,null);
type = value.GetType();
}
// here, if all goes well, property should contain the correct PropertyInfo and
// value should contain that property's value...and previousObj should contain
// the object that the property references, without which it won't do you much good.
Suppose I have a table in my database that is made up of the following columns, 3 of which uniquely identify the row:
CREATE TABLE [dbo].[Lines]
(
[Attr1] [nvarchar](10) NOT NULL,
[Attr2] [nvarchar](10) NOT NULL,
[Attr3] [nvarchar](10) NOT NULL,
PRIMARY KEY (Attr1, Attr2, Attr3)
)
Now, I have an object in my application that represents one of those lines. It has three properties on it that correspond to the three Attr columns in the database.
public class Line
{
public Line(string attr1, string attr2, string attr3)
{
this.Attr1 = attr1;
this.Attr2 = attr2;
this.Attr3 = attr3;
}
public Attr1 {get; private set;}
public Attr2 {get; private set;}
public Attr3 {get; private set;}
}
There's a second object in the application that stores a collection of these line objects.
Here's the question: What is the most appropriate design when referencing an individual line in this collection (from a caller's perspective)? Should the caller be responsible for tracking the index of the line he's changing and then just use that index to modify a line directly in the collection? Or...should there be method(s) on the object that says something to the effect of:
public GetLine(string attr1, string attr2, string attr3)
{
// return the line from the collection
}
public UpdateLine(Line line)
{
// update the line in the collection
}
We're having a debate on our team, because some of us think that it makes more sense to reference a line using their internal index in the collection , and others think there's no reason to have to introduce another internal key when we can already uniquely identify a line based on the three attributes.
Thoughts?
Your object model should be designed so that it makes sense to an object consumer. It should not be tied to the data model to the greatest extent practical.
It sounds like it is more intuitive for the object consumer to think in terms of the three attributes. If there are no performance concerns that speak to the contrary, I would let the object consumer work with those attributes and not concern him with the internal workings of data storage (i.e. not require them to know or care about an internal index).
I think the base question you are encountering is how much control the user of your API should have over your data, and what exactly you expose. This varies wildly depending on what you want to do, and either can be appropriate.
The question is, who is responsible for the information you wish to update. From what you have posted, it appears that the Line object is responsible the information, and thus I would advocate a syntax such as Collection.GetLine(attr1, attr2, attr3).UpdateX(newX) and so forth.
However, it may be that the collection actually has a greater responsibility to that information, in which case Collection.UpdateX(line, newX) would make more sense (alternatively, replace the 'line' arg with 'attr1, attr2, attr2').
Thirdly, it is possible, though unlikely (and rarely the best design IMHO) that the API user is most responsible for the information, in which case an approach you mentioned where the user handles tracking Line indices and directly modifies information.
You do not want the calling object to "track the index of the line he's changing" - ever. This makes your design way too interdependent, pushes object-level implementation decisions off onto the users of the object, makes testing more difficult, and can result in difficult to diagnose bugs when you accidentally update one object (due to key duplications) when you meant to update another.
Go back to OO discipline: the Line object that you are returning from the GetLine method should be acting like a real, first class "thing."
The complication, of course, comes if you change one of the fields in the line object that is used as part of your index. If you change one of these fields, you won't be able to find the original in the database when you go to do your update. Well, that is what data hiding in objects is all about, no?
Here is my suggestion, have three untouchable fields in the object that correspond to its state in the database ("originalAttr1", "originalAttr2", "originalAttr3"). Also, have three properties ("attr1", "attr2", "attr3") that start out with the same values as the originals but that are Settable. Your Getters and Setters will work on the attr properties only. When you "Update" (or perform other actions that go back to the underlying source), use the originalAttrX values as your keys (along with uniqueness checks, etc.).
This might seem like a bit of work but it is nothing compared to the mess that you'll get into if you push all of these implementation decisions off on the consumer of the object! Then you'll have all of the various consumers trying to (redundantly) apply the correct logic in a consistent manner - along with many more paths to test.
One more thing: this kind of stuff is done all the time in data access libraries and so is a quite common coding pattern.
What is the most appropriate design
when referencing an individual line in
this collection (from a caller's
perspective)?
If the caller is 'thinking' in terms of the three attributes, I would consider adding an indexer to your collection class that's keyed on the three attributes, something like:
public Line this[string attr1, string attr2, string attr3] {
get {
// code to find the appropriate line...
}
}
Indexers are the go-to spot for "How Do I Fetch Data From This Collection" and, IMO, are the most intuitive accessor to any collection.
I always prefer to just use a single column ID column even if there is a composite key that can be used. I would just add an identity column to the table and use that for look up instead. Also, it would be faster because query for a single int column would perform better than a key spanned across three text columns.
Having a user maintain some sort of line index to look up a line doesn't seem very good to me. So if I had to pick between the two options you posed though, I would use the composite key.
If the client is retrieving the Line object using three string values, then that's what you pass to the getter method. From that point on, everything necessary to update the object in the database (such as a unique row ID) should be hidden within the Line object itself.
That way all the gory details are hidden from the client, which protects the client from damaging it, and also protects the client from any future changes you might make to the dB access within the Line object.
I have an application that reads a table from a database.
I issue an SQL query to get a result set, based on a unique string value I glean from the results, I use a case/switch statement to generate certain objects (they inherit TreeNode BTW). These created objects get shunted into a Dictionary object to be used later.
Whilst generating these objects I use some of the values from the result set to populate values in the object via the setters.
I query the Dictionary to return a particular object type and use it to populate a treeview. However it is not possible to populate 2 objects of the same type in a treeview from the Dictionary object (you get a runtime error - which escapes me at the moment, something to with referencing the same object). So what I have to do is use a memberwiseClone and implement IClonable to get around this.
Am I doing this right? Is there a better way - because I think this is causing my program to be real slow at this point. At the very least I think its a bit clunky - any advice from people who know more than me - greatly appreciated.
Is there a reason you are using the external dictionary? I would populate the tree directly as the data is queried.
If you do require the dictionary, you could set the .Tag property of the tree node to point to the data in your dictionary.
To add to #Brad, only populate the tree as needed. That means hooking into the expand event of the tree nodes. This is similar to how Windows Explorer functions when dealing with network shares.
There should be 1 TreeNode object per actual tree node in the tree - don't try to reuse the things. You may either associate them with your data using the Tag property (this is the recommended method), or you can subclass the TreeNode itself (this is the Java method, but used less in .NET).
(The use of cloning methods is usually a hint that you're either (a) doing something wrong, or (b) need to factor your domain model to separate mutable objects from immutable.)
have you considered using a Virtual Tree view which only loads the nodes the user actually wants to look at - i've had good success with the component from www.infralution.com