How to compare two objects by value - wpf

I need to compare two objects of the same class by value to see whether all their values match or not.
For background this is so I can compare before and after values of a wpf datagrid row
Say the objects are both House class with properties of name, street, town (all strings).
So the class would be
public class House
public property name as string
public property street as string
public property town as string
end class
Should I
1) override equals in the House class and in it check name=name, street=street, town=town
2) make the House class implement IComparable and create a compare function that implements it, checking each property as 1
3) there's a better way you know that I dont!
I'd appreciate an example based on this scenario if possible.
Many thanks

You should be using Option 1 : Overriding the Equals method.
Why ?
Because the Equals() method is supposed to be used when you want to compare if two objects are the same.
So what's the use of IComparabe ?
IComparable interface has a different purpose. Its goal is to check if an object is supposed to go before or after another object. Therefore this is used by sorting methods.
You can implement the IComparable interface and check if two object's CompareTo() method return 0. However it only means that they are supposed to get the same ranking, not that they are equals...
Is there another approach ?
There are plenty differents ways of doing what you want to do. But since there is a simple and elegant method that is here, let's use that one. The main difficulty in programming an application is to find the tools that are already here to do what you want...
So how to Override the Equals() method ?
This link to MSDN explains how to override the Equals method
In short (I'm just copy/pasting from MSDN and removing error checking for clarity here) :
Public Class Point
Protected x As Integer
Protected y As Integer
Public Sub New (xValue As Integer, yValue As Integer)
Me.x = xValue
Me.y = yValue
End Sub
Public Overrides Overloads Function Equals(obj As Object) As Boolean
Dim p As Point = CType(obj, Point)
Return Me.x = p.x And Me.y = p.y
End Function
End Class
Do not use this straight ahead and read article first, as you must do some error checking in the Equals, because it could throw some exception when converting Object to Point...

Related

How do I redefine the class of a variable programmatically?

Ok, so I have 2 classes, Note and HeldNote. HeldNote inherits from Note and adds only 2 variables, plus a different way of setting visual dimensions. I have an array of an undefined amount of items, with each item defined as a member of class Note.
Occasionally during my program, I want one of these items in the array to be a HeldNote rather than a Note, and I do not know which one until the program is running.
VB.Net seems fine with me declaring array(i) = New HeldNote but then wont let me access the variables that HeldNote has but Note does not. Using Breaks in the program leads me to believe that array(i) is not actually being redefined as a HeldNote rather than a Note.
So, my question is, how can I make array(i) a HeldNote, rather than a Note?
I'm using VB.net 2008.
Edit: I asked my Teacher about this problem and he said he didn't know and told me to look it up. I couldn't anything online (had been looking since before i asked him) so I've come here for help.
The Array of Note (better use a List(Of Note) if you are unsure about the size) can store both Note and HeldNote because the latter derives from the first.
But, when you store an HeldNote in the array it is not automatically transformed in a Note, it is still an HeldNote, what you need is to try casting it back to an HeldNote
For example
Sub Main
Dim X(2) As Note
X(0) = New Note() WIth {.Note = "A Message"}
X(1) = New HeldNote() With {.Note = "Held Message", .Author = "Steve"}
Dim h As HeldNote
h = TryCast(X(0), HeldNote)
If h Is Nothing Then
Console.WriteLine("X(0) is NOT an HeldNote")
Else
Console.WriteLine(h.Author)
End If
h = TryCast(X(1), HeldNote)
If h Is Nothing Then
Console.WriteLine("X(1) is NOT an HeldNote")
Else
Console.WriteLine(h.Author)
End If
End Sub
Public Class Note
Public Note As String
End Class
Public Class HeldNote
Inherits Note
Public Author As String
End Class
In thisway you still have your HeldNote without using an array of Object that is something to avoid because you loose all the strong typing allowed by a specific Note array (In an Object array you could store anything. A Button or a String makes no difference)
A few suggestions:
1) Change your design and have just one class rather than one that inherits from another.
2) Declare your array as type Object. Each element of an Object array can be of a different type. This way you can assign each element's type at runtime.
Dim notearray As Object() = New Object() {New Note(), New HeldNote(), New HeldNote(), New Note()}
This is not a code issue, it's almost a OO question.
"I have an array of an undefined amount of items, with each item defined as a member of class Note."
Then all of them are "Note". You can create class instances so:
Note theNote = new HeldNote()
but you can't "downgrade" a instance on execution declared so:
Note theNote = new Note()".
If you need "randomly" a type change, you can create a ListOf(HeldNote).
Then, you can decide the real type so:
Dim aList as new ListOf(HeldNote)
aList.add(new HeldNote())
aList.add(new HeldNote())
aList.add(new HeldNote())
Dim oNote as Note
oNote = Ctype(aList(0),Note)
Dim oNote as HeldNote
oNote = aList(1)
...

Use of Wrapper class for deserialization in callout?

I found the following use of a wrapper class, and was wondering if it is a good practice or whether its just duplication of code for no reason.
//Class:
public class SomeClass{
public Integer someInt;
public String someString;
}
//Callout Class:
public class CalloutClass{
public SomeClass someMethod(){
//...code to do a callout to an api
SomeClass someClassObj = (SomeClass)JSON.Deserialize(APIResponse.getBody(), SomeClass.class);
return someClassObj;
}
}
//Controller:
public class SomeController {
public SomeController(){
someClassObj = calloutClassObj.someMethod();
SomeWrapper wrapperObj = new SomeWrapper();
for(SomeClass iterObj : someClassObj){
wrapperObj.someWrapperInt = iterObj.someInt;
wrapperObj.someWrapperString = iterObj.someString;
}
}
public class someWrapper{
public Integer someWrapperInt{get;set;}
public String someWrapperString{get;set;}
}
}
The wrapper class "someWrapper" could be eliminated if we just use getters and setters ({get;set;}) in "SomeClass."
Could anyone explain if there could be a reason for following this procedure?
Thanks,
James
My assumption (because, code in controller is extra pseudo) is
SomeClass is a business entity, purpose of which is to store/work with business data. By work I mean using it's values to display it (using wrapper in controller), to calculate smth in other entities or build reports... Such kind of object should be as lightweight as possible. You usually iterate through them. You don't need any methods in such kind of objects. Exception is constructor with parameter(s). You might want to have SomeObject__c as parameter or someWrapper.
someWrapper is a entity to display business entity. As for wrapper classes in controllers. Imagine, that when you display entity on edit page and enter a value for someWrapperInt property, you want to update someWrapperString property (or you can just put validation there, for example, checking if it is really Integer). Usually, as for business entity, you don't want such kind of functionality. But when user create or edit it, you may want smth like this.

Dynamic Array as Class Property in VBScript

I am very new to VBScript, and not entirely sure if what I am doing is right.
I want to create a structure to hold onto a string and then an array of strings. The array of string will be dynamic, as I do not know how many entries are going to be in that list.
I have the following:
Class ExportMappings
Private _process_definition
Private _export_mappings : Set _export_mappings = CreateObject("System.Collection.ArrayList")
Public Property Let ProcessDefinition(procDef)
_process_definition= procDef
End Property
Public Property Get ProcessDefinition()
ProcessDefinition = _process_definition
End Property
Public Property Let ExportMappings(export)
_export_mappings = export
End Property
Public Sub AddMapping(map)
_export_mappings.Add map
End Sub
End Class
First, I am not sure if I declared the _export_mapping array properly.
Secondly, I do not know if I need a constructor to initialize my _export_mappings to an initial size. If so, I do not know how I would do that.
Lastly, my get and set methods for ExportMapping, I am not sure if that will work.
I would try to run it through a debugger, but the software I am using does not have the best debugger, and usually gives me a very vague description of what is wrong.
First things first:
VBScript variable names can't start with _; you can 'legalize' invalid names by putting them in [], but for starters I wouldn't do this
Code in Classes is allowed in methods only; your Private _export_mappings : Set _export_mappings = CreateObject("System.Collection.ArrayList") is invalid
After these changes, your code should compile. If you add code showing how you'd like to use this class, I'm willing to talk about second things (maybe tomorrow).

Override Comparable interface for GAE property?

I'm not sure if this is possible at all, but is there a way to override the Comparable used by a Google App Engine property when used in a query? For example, there is a property type PhoneNumber (basically a String) that in the docs has a method:
public int compareTo(PhoneNumber o)
Specified by:
compareTo in interface java.lang.Comparable<PhoneNumber>
The exact workings of how it compares I haven't been able to find. Is there a way to override that Comparable so that it compares it in a way I choose?
Thanks
No. But you can sort any collection any way you want. Since you tagged this with objectify:
#Entity
public class Thing {
private static final Comparator<PhoneNumber> SPECIAL_COMPARATOR = // make one
// ... id, etc
SortedSet<PhoneNumber> phoneNumbers = new TreeSet<>(SPECIAL_COMPARATOR);
}
This won't help you if you need the phone numbers indexed in a particular way (although collection property index sorting would be very strange anyways). If you have a single indexed phone number property and you want to control index ordering, you need to create your own PhoneNumber that translates to a correctly-sorted String representation. You'll need to register your own PhoneNumberTranslatorFactory with Objectify. This is not hard; look at the source code for examples.

Pass data between WPF windows

I have some code that works in winforms, but not in WPF apparently, the code is as follows:
This is set globally:
Private Property avar As Object
Public main As MainWindow
Public charchoice As Char
And then in the Window Loaded sub, this is placed:
charchoice = main.charchoice
Thing is, the next window doesn't pick up this variable, so how can I make it recognise and use it? Thanks Guys
Nick
I had a similar problem and discovered that you must create a public property in the MainWindow and pass a value to the property.
Please see this example from a similar question I posted.
Hey i got same problem when i am going to pass values between two forms.
I find its solution using a simple class and Shared property.
First I create a class named with cls_pass_val which is as under:-
Public Class cls_pass_val
Private Shared var_pass_val As String = ""
Public Shared Property Pass_val() As Char
Get
Return var_pass_val
End Get
Set(ByVal value As String)
var_pass_val = value
End Set
End Property
End Class
Now at the time of assigning a value:
cls_pass_val.Pass_val='A'
and at the time of retrieving the value:
Dim var_c as Char
var_c=cls_pass_val.Pass_val

Resources