|
Are there any recommended resources for getting started with WPF in .net4.0? I mostly work on web stuff but have a project that needs to be a desktop app.
|
# ? Dec 17, 2011 17:10 |
|
|
# ? Apr 19, 2024 18:19 |
|
WPF 4 Unleashed was a good read, full of examples and screenshots.
|
# ? Dec 17, 2011 17:20 |
|
Anyone have any suggestions for how to incorporate a nice C# script editor into a program? Right now I'm just using a regular textbox as an editor and then compiling that result and running it. This works, but the lack of editing/formatting/intellisense tools makes it feel clunky as heck and the user has to know what objects/methods are available by memory alone. I've checked out several projects posted around the internet but none of them really look all that great. Ideally I'd like to pop open a scripting form, tell it what objects the script is allowed to access, and then have it feel as much like a mini version of Visual Studio as possible.
|
# ? Dec 18, 2011 16:51 |
|
Take a look at how LINQPad does it: http://www.linqpad.net/HowLINQPadWorks.aspxquote:LINQPad uses a number of third-party components within the UI. The query editor uses Actipro's SyntaxEditor control (a very polished product); the "IntelliSense" features rely on a combination of libraries from Actipro Software and ICSharpCode (from the SharpDevelop project).
|
# ? Dec 18, 2011 19:06 |
|
Is it possible to have a gradient run the length of an arc in WPF? I have seen this post which seems to indicate a goofy amount of code is required (so, par for WPF) but the example is a geometry path, not an arc, so I'm hoping to find some trick that will make it simple.
|
# ? Dec 18, 2011 23:24 |
|
If I've got to marshal a goofy hierarchy of structures including dynamically-allocated native arrays, is it reasonable that I'm going to end up doing pointer arithmetic on some IntPtrs? I can't find anything useful in Marshal for "copy this as a variable-length array of this type." Also, do I need to pin value types that live on the stack if I'm P/Invoking them into native code? raminasi fucked around with this message at 00:10 on Dec 20, 2011 |
# ? Dec 20, 2011 00:03 |
|
P/Invoking with variable length arrays is kind of a pain in the rear end. Fixed length you can use MarshalAs.SizeConst but you already knew that. If you're marshalling a variable length array of primitives, you can use various overloads of Marshal.Copy: code:
You only need to pin reference types (especially callbacks) so the unmanaged pointer doesn't outlive the managed object.
|
# ? Dec 20, 2011 03:00 |
|
I'm working on a small project in c# and have a quick question: I created a class that inherits Object and overrides .Equals(). The compiler is warning me because I am not overriding .GetHash() as well. Do I really need to do this if I'm never actually going to use that method myself?
|
# ? Dec 20, 2011 23:15 |
|
Just do it and return base.GetHashCode(). Note that you may have decreased performance when you use your object in various collections that use hashing, like a Dictionary.
|
# ? Dec 20, 2011 23:29 |
|
Admiral Snackbar posted:I'm working on a small project in c# and have a quick question: I created a class that inherits Object and overrides .Equals(). The compiler is warning me because I am not overriding .GetHash() as well. Do I really need to do this if I'm never actually going to use that method myself?
|
# ? Dec 20, 2011 23:56 |
|
Admiral Snackbar posted:I created a class that inherits Object All classes inherit from object.
|
# ? Dec 21, 2011 00:59 |
|
Ithaqua posted:All classes inherit from object. I know you're trying to get exactly this response to prove the point, but presumably he means it inherits directly from object with no intermediary class(es).
|
# ? Dec 21, 2011 01:11 |
|
Admiral Snackbar posted:I'm working on a small project in c# and have a quick question: I created a class that inherits Object and overrides .Equals(). The compiler is warning me because I am not overriding .GetHash() as well. Do I really need to do this if I'm never actually going to use that method myself? The other answers you got are fairly lovely, since they don't explain why you should or shouldn't override .GetHashCode(). You should override .GetHashCode() if two different instantiations of your class should be considered equal depending on their state. This is almost always the case when you're overriding .Equals(), otherwise you wouldn't bother overriding it, so the advice to not override it is probably wrong. You will not simply get decreased performance for calling base.GetHashCode()--you'll get different behavior. See the following: Without .GetHashCode() override With .GetHashCode() override If your value-typed object has more than one value that determines equality, you should combine the hashes. A fairly terrible way to do it is to simply: return value1.GetHashCode() ^ value2.GetHashCode(); Ignore everything after this if it's for homework Better, but still lovely is: code:
wellwhoopdedooo fucked around with this message at 01:34 on Dec 21, 2011 |
# ? Dec 21, 2011 01:30 |
|
wellwhoopdedooo posted:The other answers you got are fairly lovely, since they don't explain why you should or shouldn't override .GetHashCode(). You still didn't explain why! Though you at least demonstrated it. Even if your own code never calls .GetHashCode(), infrastructure (such as the Dictionary class) does call it, and depends upon hash code equality being equivalent to object equality.
|
# ? Dec 21, 2011 01:44 |
|
Zhentar posted:You still didn't explain why! Though you at least demonstrated it.
|
# ? Dec 21, 2011 02:12 |
|
No Pants posted:It depends on what you're using that class for, but you probably don't need to override GetHashCode. You should just have it return a constant value in case something else uses that function.
|
# ? Dec 21, 2011 02:31 |
|
No Pants posted:It depends on what you're using that class for, but you probably don't need to override GetHashCode. You should just have it return a constant value in case something else uses that function. Do not do this. Never, ever do this. If your object has a logical key, return its hash. pre:return CustomerId.GetHashCode(); If your object has a composite logical key, return the hash of it's componants. pre:return CustomerId.GetHashCode() ^ ItemId.GetHashCode(); Dietrich fucked around with this message at 02:47 on Dec 21, 2011 |
# ? Dec 21, 2011 02:45 |
|
On the whole implementing GetHashCode() overrides thing, is there any reason you all are using exponents? In most cases where I've done this and there were multiple values, I just concatenated all the values together in a big string and then called GetHashCode() on that.
|
# ? Dec 21, 2011 04:04 |
|
wwb posted:On the whole implementing GetHashCode() overrides thing, is there any reason you all are using exponents? In most cases where I've done this and there were multiple values, I just concatenated all the values together in a big string and then called GetHashCode() on that. I've heard it explained before it is to get a better range of hashes which (somehow, I don't know) improves the hash lookups. Also, technet has a nice article on what you need to do when overriding equals & Hashcode (http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx). e: for what it's worth the last time i needed to override getequals I was never able to get it quite right, so you know i'm probably wrong here. e2: Yeppppppppp VVVVVVVVV adaz fucked around with this message at 04:17 on Dec 21, 2011 |
# ? Dec 21, 2011 04:09 |
|
wwb posted:On the whole implementing GetHashCode() overrides thing, is there any reason you all are using exponents? In most cases where I've done this and there were multiple values, I just concatenated all the values together in a big string and then called GetHashCode() on that. That's not an exponent, that's the xor operator. Bitwise operators, ahoy!
|
# ? Dec 21, 2011 04:16 |
|
wwb posted:On the whole implementing GetHashCode() overrides thing, is there any reason you all are using exponents? In most cases where I've done this and there were multiple values, I just concatenated all the values together in a big string and then called GetHashCode() on that. Do not do that either. Concatenating strings in .net is a truck load of slow. Although this is less bad than the constant idea, it would only suck for you if you were trying to load a hash table with a large number of your objects, or compare your object with a large number of other objects or something.
|
# ? Dec 21, 2011 04:36 |
|
Ithaqua posted:All classes inherit from object. rolleyes posted:I know you're trying to get exactly this response to prove the point, but presumably he means it inherits directly from object with no intermediary class(es). Funnily enough, one of the example for Equals on msdn explicitly subclasses Object. code:
|
# ? Dec 21, 2011 04:37 |
|
When you declare a class, and don't type : Object or : SomethingElse the compiler helpfully adds : Object for you.
|
# ? Dec 21, 2011 04:39 |
|
What in the hell happened here? Here's my two cents: If you override .Equals, and you're going to use your new class in a collection of some sort (or, iirc, serializing, or implementing one of several different types of interfaces) -- you owe it to yourself to implement .GetHashCode as well. Hashes should be cheap to calculate (see Dietrich's warning against concatenating for what not to do), and echo the same logic as .Equals For reference, see the MSDN page on the GetHashCode method. Although to be perfectly clear, I'm not sure why their third example uses constants for .GetHashCode. Seems like a bad way to illustrate the concept.
|
# ? Dec 21, 2011 05:50 |
|
So a question that can come up (or at least I've had) - is say you have a class with an arbitrary number of properties as - say - strings, or an array in there or two. If you want to override equals to provide value equality between two objects of that same class what's your best bet? Because concatenating strings and then running GetHash() is apparently not efficient.
|
# ? Dec 21, 2011 06:07 |
|
There are a number of snags when implementing Equals/GetHashCode. To name a few: - Equals not matching GetHashCode. For example, if Equals compares two strings case-insensitive, you should use a case-insensitive hash code. - Mutable objects - always good to avoid them, but especially here. Mutating an object changes its hash, breaking anything that depends on the hash, like if the object was being used in a hash set. - Subclassing can break the contract if you're not careful. See how the official examples use GetType() != obj.GetType(). If you don't do this, you can come up with cases where A.Equals(B) != B.Equals(A). Worst of all, problems might only manifest in very specific circumstances. adaz posted:So a question that can come up (or at least I've had) - is say you have a class with an arbitrary number of properties as - say - strings, or an array in there or two. If you want to override equals to provide value equality between two objects of that same class what's your best bet? Because concatenating strings and then running GetHash() is apparently not efficient. You should be concerned if you're using too many/too complex properties as a key. You should think about what makes two instances equal. Must they have the exact same values in the array?
|
# ? Dec 21, 2011 06:34 |
|
Sedro posted:This advice is still valid. Returning a constant will result in a hash collision and fall back on Equals every time. See here. It's not much trouble to just implement it though. No, it's terrible advice. You're right in the sense that it won't result in a Dictionary (or HashSet, or similar) suddenly returning incorrect answers, but they still won't function properly. Pretty much the entire point of using a Dictionary is its constant-time lookups, and by returning a constant value, you're breaking that behavior. Going from O(1) to O(n) is not a good thing. adaz posted:So a question that can come up (or at least I've had) - is say you have a class with an arbitrary number of properties as - say - strings, or an array in there or two. If you want to override equals to provide value equality between two objects of that same class what's your best bet? Because concatenating strings and then running GetHash() is apparently not efficient. Sedro posted:Your Equals should match your GetHashCode. If you compare 5 properties for equality, you should compose those same 5 properties into a hash code. The 5 combined values function as a composite key to the object. Whenever I've needed to combine the hashes of multiple fields, I used this code, which (as far as I can remember) was taken from boost::hash_combine. code:
"Calls to hash_combine incrementally build the hash from the different members of point, it can be repeatedly called for any number of elements."
|
# ? Dec 21, 2011 10:01 |
|
boo_radley posted:I'm not sure why their third example uses constants for .GetHashCode. Seems like a bad way to illustrate the concept. We need a for MSDN. MSDN documentation is terrible.
|
# ? Dec 21, 2011 13:39 |
|
Dietrich posted:We need a for MSDN. Compared to what?
|
# ? Dec 21, 2011 14:25 |
|
Wow, thanks for all the feedback! If I could, I'd like to run this by you folks to see if it's sufficient. Suppose my class is called Boob, and it has two properties: CupSize and NippleSize, both of which are strings. My Equals() method would be: code:
and my GetHashCode() would be: code:
|
# ? Dec 21, 2011 14:44 |
|
Admiral Snackbar posted:
I'd generally advise against simply XORing hashes, because it can easily make hash collisions more likely. See wellwhoopdedooo's or my previous post for suggestions for combining hashes.
|
# ? Dec 21, 2011 15:39 |
|
wellwhoopdedooo posted:Compared to what? C# In Depth. Written by one guy. Who doesn't even work in .net full time.
|
# ? Dec 21, 2011 16:42 |
|
Admiral Snackbar posted:
You mentioned CupSize and NippleSize are strings, so that should be... code:
http://msdn.microsoft.com/en-us/library/cc165449.aspx posted:When you compare strings, you should use the methods that explicitly specify what kind of comparison you intend to perform. This makes your code much more maintainable and readable. Whenever possible, use the overloads of the methods of the System.String and System.Array classes that take a StringComparison enumeration parameter, so that you can specify which type of comparison to perform. It is best to avoid using the == and != operators when you compare strings. Also, avoid using the String.CompareTo instance methods because none of the overloads takes a StringComparison.
|
# ? Dec 21, 2011 16:50 |
|
dwazegek posted:No, it's terrible advice. You're right in the sense that it won't result in a Dictionary (or HashSet, or similar) suddenly returning incorrect answers, but they still won't function properly. Pretty much the entire point of using a Dictionary is its constant-time lookups, and by returning a constant value, you're breaking that behavior. Going from O(1) to O(n) is not a good thing. My C++ is non-existent but I want to make sure I'm understanding how this works, because overloading equals/hash code is something I will eventually need to do and I've always wanted to make sure I do it correctly. From what I got here and looking at the boost documentation you start with an initial seed of 0, and the other parameter you are taking a hash value off of the values you're trying to combine. So, if you're using a string or something with .NET you could pass this the .GetHashCode() off the string with a seed of 0 and then move through each of the values you wish to combine using the supplied algorithm (which does some magic I don't really care about as long as it combines the hashes correctly). Sound right?
|
# ? Dec 21, 2011 16:52 |
|
Great - thanks everyone!
|
# ? Dec 21, 2011 16:57 |
|
Dietrich posted:
On the contrary, returning a constant from GetHashCode is pretty reasonable: http://blogs.msdn.com/b/jaredpar/archive/2008/06/03/making-equality-easier.aspx But the most basic rule is: "Only calculate the hash code based off of primitive fields which are ReadOnly" http://blogs.msdn.com/b/jaredpar/archive/2008/04/28/properly-implementing-equality-in-vb.aspx
|
# ? Dec 21, 2011 17:00 |
|
epswing posted:You mentioned CupSize and NippleSize are strings, so that should be... The (in)equality operators will just call .Equals themselves (or vice versa), so your example really isn't any different or better. I think the more important part of the quote is this part: quote:When you compare strings, you should use the methods that explicitly specify what kind of comparison you intend to perform. So you should be using Equals(string, StringComparison) (or an equivalent comparer from the StringComparer class). adaz posted:Sound right? Yep.
|
# ? Dec 21, 2011 17:03 |
|
ljw1004 posted:On the contrary, returning a constant from GetHashCode is pretty reasonable: For a certain value of reasonable, I suppose. Jared's post is written from the perspective of satisfying a minimum base set of criteria for the BCL. He only addresses the performance hit after his sample: quote:Of course this does come with a trade off. As said before GetHashCode() is primarily used as a bucketing mechanism. It will cause the performance of bucketing collections such as Dictionary or Hashtable to drop from close to O(1) to O(N). But once again this is not a bug but a conscious trade off. It's a bit perverse to say "this is the absolute bare minimum you really need to do to satisfy BCL" rather than helping people understand how to write performant code -- or at least write less terrible code. It might be making your fields read-only, or extending your class to account for mutable fields (ex. hash caching), but there has to be a better option than a static hash value.
|
# ? Dec 21, 2011 18:11 |
|
He's saying it's a design decision. If you aren't designing your class to be used in one of those collections, it's fine.
|
# ? Dec 21, 2011 18:33 |
|
|
# ? Apr 19, 2024 18:19 |
|
No Pants posted:He's saying it's a design decision. If you aren't designing your class to be used in one of those collections, it's fine. I too enjoy having to make sure that the GetHashCode implementation is not poo poo every time I use a class in a collection. If you're writing a throw away test class, sure. If you're writing anything else, just take the extra half a second and return the hash code of the logical key.
|
# ? Dec 21, 2011 18:40 |