|
If it's COM, probably an interop assembly to a type library. Or are we talking about COM serial ports?
|
# ? Nov 15, 2011 07:04 |
|
|
# ? Apr 23, 2024 10:17 |
|
ljw1004 posted:Is it a .NET assembly rather than a plain old win32 DLL? Is it really "your library"? If so, I wonder if MEF might work. It's entire purpose is to allow loose coupling between assemblies in this sort of way. My program is .NET, the driver is a win32-style DLL that is supplied by the hardware manufacturer. I don't have access to the driver source code so I think MEF is out in this case. Thanks for the suggestion though. Sedro posted:If it's COM, probably an interop assembly to a type library. Or are we talking about COM serial ports? Yep, it's COM as in Common Object Model, not as in COM1 serial port. At this point I'm thinking about hiding the actual driver code behind some interface, and then creating a do-nothing placeholder class that implements that same interface. At startup I'd attempt to create the actual driver class but if that process fails due to the DLL not existing I'd return the placeholder class instead. I usually abstract all my hardware devices as interfaces anyway for testing purposes so making the placeholder class won't really even be much extra work.
|
# ? Nov 15, 2011 16:40 |
|
Wrap the driver in your own .NET assembly and use MEF to dynamically load it?
|
# ? Nov 15, 2011 17:28 |
|
Smugdog Millionaire posted:Wrap the driver in your own .NET assembly and use MEF to dynamically load it? I'd still have to probe for the existence of the driver in the wrapper code and fall back gracefully somehow if it doesn't exist, so I'm not sure that this would solve the problem so much as it would move it to another place. Let me know if I'm wrong though, I'm no MEF expert so there may be something I'm missing.
|
# ? Nov 15, 2011 18:02 |
|
I'm an experienced programmer with backgrounds in Perl, Python, Ruby, C and a few other languages looking to get up to speed with .NET and the CLR in as little time as possible for a project I'm working on. Specifically, I want to focus on conventions and the way that .NET developers do things that might not be implicit in the language itself. Where should I start?
|
# ? Nov 15, 2011 19:13 |
|
Conventions are specific to language and not .NET in general. Which language are you working with for your project? C#, F#, VB.NET, one of the others which targets the CLR?
|
# ? Nov 15, 2011 19:21 |
|
csammis posted:Conventions are specific to language and not .NET in general. Which language are you working with for your project? C#, F#, VB.NET, one of the others which targets the CLR?
|
# ? Nov 15, 2011 19:29 |
|
What would be the fastest/best way to implement a Tree View in WinForms? Was reading on SO you could create a WPF TreeView control and use ElementHost to have the WPF control in WinForms but I'm not familiar with WPF or creating controls, would this be fairly simple or not so much?
|
# ? Nov 15, 2011 19:33 |
|
WinForms doesn't have a TreeView? WPF's TreeView is very limited so I wouldn't recommend using that (even in WPF). It wouldn't be simple to create one with either technology. The best/fastest way is to find one off the shelf.
|
# ? Nov 15, 2011 19:42 |
|
Mr. Crow posted:What would be the fastest/best way to implement a Tree View in WinForms? Was reading on SO you could create a WPF TreeView control and use ElementHost to have the WPF control in WinForms but I'm not familiar with WPF or creating controls, would this be fairly simple or not so much? I use the winforms treeview control, which is pretty ok.
|
# ? Nov 15, 2011 19:55 |
|
PDP-1 posted:I could dynamically load the DLL using Assembly.LoadFrom("myLibrary.dll") but that's really ugly since the IDE doesn't have a way to know the internal DLL types which would make programming the interface painful as I'd have to call everything via reflection and manually cast. That's not quite true... Here's a different idea. (1) Develop your application in the way you did up until now, by adding a reference. So at least you can develop using intellisense and type-checking. (2) But then, use the new "dynamic" pseudo-type. It's entire purpose is to make it easier to late-bind to different assemblies. code:
|
# ? Nov 15, 2011 20:36 |
|
PDP-1 posted:I'd still have to probe for the existence of the driver in the wrapper code and fall back gracefully somehow if it doesn't exist, so I'm not sure that this would solve the problem so much as it would move it to another place. I guess I misunderstood the problem statement. I thought you had control over driver distribution and could distribute the .NET wrapper along with it.
|
# ? Nov 15, 2011 21:53 |
|
Mr. Crow posted:What would be the fastest/best way to implement a Tree View in WinForms? Was reading on SO you could create a WPF TreeView control and use ElementHost to have the WPF control in WinForms but I'm not familiar with WPF or creating controls, would this be fairly simple or not so much? http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aspx It's not the most flexible and wonderful treeview in the world, but you haven't specified any functionality that would make it ineligible for use... edit: I guess this was mentioned a few times before me. slow typing.
|
# ? Nov 15, 2011 22:41 |
|
ljw1004 posted:That's not quite true... Here's a different idea. When I wrote that stuff you quoted I was operating under the incorrect assumption that just having a reference in my project would cause the application to resolve the COM interface at start-up. No idea why I thought that was true, but realizing that the COM references only kick in when you first interact with the driver makes everything simpler. I can just try/catch around the first instantiation of the driver and handle things from there. The idea of using a dynamic variable is pretty interesting since the final version of the code wouldn't need specific references to anything at all. I'll have to think about it a bit, but it could wind up being more portable. Thanks to everyone for the suggestions and help! e: Smugdog Millionaire posted:I guess I misunderstood the problem statement. I thought you had control over driver distribution and could distribute the .NET wrapper along with it. Yeah it's a bit of an unusual situation in that the application should be usable whether or not a particular bit of hardware is plugged into a USB port. If the hardware isn't present I don't want to require the driver to be present either. Most of the users will never have the hardware connected so forcing them to install drivers would just be confusing for them. PDP-1 fucked around with this message at 22:50 on Nov 15, 2011 |
# ? Nov 15, 2011 22:44 |
|
genki posted:Uh, use the builtin WinForms TreeView? Well I was hoping for an easily implemented more flexible approach so I wouldn't have to re-write it later when we eventually move it to the end-user GUI, but I don't have the time to spend on it at the moment, just need a basic TreeView for internal use atm. And now I'm running into another issue, how do I get the generic type of a parent? Basically I have child : parent<T> and I want T. I can use child.GetType().BaseType.GetGenericArguments() but that is annoying because it has a bunch of assumptions. Mr. Crow fucked around with this message at 00:52 on Nov 16, 2011 |
# ? Nov 15, 2011 23:48 |
|
I can't imagine how else you'd do it. "type" in parent<type> isn't the parent's type, the parent's type is parent<type>. Imagine if you had parent<type1, type2> instead, which one would you expect to get as the parent "type"?
|
# ? Nov 16, 2011 00:12 |
|
Was copy/pasting code and not what is actually going on, so I'm not trying to get the base of the parent, I'm getting the base of the child (so in our example, parent). Check edit. Also I'd expect to get type1 and type2, GetGenericArguments returns an array. Basically I'd like a way to do is, however many layers up the hierarchy, there is eventually a parent<T> that I'd like to get. The problem is right now it's assumed it's the immediate parent (which in this case it is and I'm fine with leaving it like that for now).
|
# ? Nov 16, 2011 00:51 |
|
You can walk up the inheritance hierarchy until you hit a parent:code:
|
# ? Nov 16, 2011 01:27 |
|
Yeah what he said. There really isn't an elegant way to deal with WinForms Tree control hierarchy (e.g. that doesn't involve a for next/while per level) unless you have the original hierarchy definition in another format (e.g. XML).
|
# ? Nov 16, 2011 02:06 |
|
PDP-1 posted:I'd still have to probe for the existence of the driver in the wrapper code and fall back gracefully somehow if it doesn't exist, so I'm not sure that this would solve the problem so much as it would move it to another place. You might be able to try some trickery within the wrapper code by delay loading the native code, and using the __pfnDliFailureHook2 to handle when it can't be loaded properly, and then you can gracefully fallback onto whatever you need to. However, the documentation on this is extremely sparse, so you may want to look for an alternative. edit: Actually ignore this, I'm not really paying attention it seems.
|
# ? Nov 16, 2011 07:01 |
|
Mr. Crow posted:Basically I have child : parent<T> and I want T. Can you modify the parent class? You could just add a method to Parent<T> that returns typeof(T).
|
# ? Nov 16, 2011 08:05 |
|
Zhentar posted:Can you modify the parent class? You could just add a method to Parent<T> that returns typeof(T).
|
# ? Nov 16, 2011 08:15 |
|
Orzo posted:I think he means to do it in an abstract way for all cases...adding that method is pretty shoddy design. Basically, although now a similar question (same piece of code), how do I cast a generic? Again, I've created an instance of the T from before, but now I'm trying to actually wire the two together. Parent (which is a collection) has the following, abstract Parent<T> where T : ICommon, now that I've got a concrete item T, how do I add T to the Parent collection? ((Parent<ICommon>) parent).Add(T) compiles but then throws cast exceptions.
|
# ? Nov 16, 2011 20:37 |
|
Mr. Crow posted:Basically, although now a similar question (same piece of code), how do I cast a generic? I am curious as to exactly how this frankenstein-type requirement came to be? What exactly is the use case such that you need to be able to do this kind of thing? Does it involve a 3rd party, by any chance? I would hate to think any internal design would allow this kind of reflection nonsense to be required (though I suppose in a large enough company, it's entirely possible...) I also have to assume that speed/performance aren't major limitations?
|
# ? Nov 16, 2011 21:30 |
|
genki posted:I know this is possible but unfortunately I can't look up/test the specifics atm. It's not possible to cast parent to Parent<ICommon> unless T is ICommon. You can only use covariance with interfaces, and even then you shouldn't be able to make something with an Add function covariant. I don't know if there's a way to cast it to Parent<T>, but it definitely sounds to me like the kind of question you shouldn't need to ask in the first place.
|
# ? Nov 16, 2011 21:42 |
|
Yeah...I might be reading this wrong, but why not just cast to Parent<T>? Since T must implement ICommon, it should have the Add method available.
|
# ? Nov 16, 2011 21:46 |
|
completely the wrong thread! n/m.
|
# ? Nov 16, 2011 21:53 |
|
Orzo posted:Yeah...I might be reading this wrong, but why not just cast to Parent<T>? Since T must implement ICommon, it should have the Add method available. You'd think that (and they do) but it doesn't let me do that, it was the first thing I tried (hence the comment about having the ICommon constraint). Very annoying to be sure and I was hoping someone would answer why it doesn't work, among any other bits of info. genki posted:I know this is possible but unfortunately I can't look up/test the specifics atm. Yes it half involves a 3rd party standard. Basically according to the spec they have collections defined as separate entities (which translates to like 30 separate wrapper classes for a list), so I have a collection base Parent<T> that all the wrapper classes inherit from, and the T tells me what the actual lists objects are supposed to be. Supposed to be being the crucial problem, I can't genericize everything/list itself because I don't actually know what kind of data I'm going to be reading in and can't assume it's valid data, so in the base the list is just a List<ICommon> so it can be validated later. It's for convenience in other area's (like it should have been here).
|
# ? Nov 16, 2011 22:54 |
|
I'm actually having a little trouble following the way your pieces fit together Mr Crow...could you paste something more complete on pastebin or something? Maybe like a simplified version of your system.
|
# ? Nov 16, 2011 22:57 |
|
Mr. Crow posted:Supposed to be being the crucial problem, I can't genericize everything/list itself because I don't actually know what kind of data I'm going to be reading in and can't assume it's valid data, so in the base the list is just a List<ICommon> so it can be validated later. It's for convenience in other area's (like it should have been here). So it's a List<ICommon> (or something much like it) which means everything in it is guaranteed to be an ICommon. But then it sounds like the collection contains heterogeneous implementations of ICommon, of which you need to know the actual type (or parent type) after pulling it out of the collection? Am I getting that right? This sounds like a disaster of a design. Like you know you have an ICommon but in case A you need an ICommon that is also a FooParent but in case B you need an ICommon that is also a BarParent and that information is lost by the collection since everything is typed to ICommon. Basically it's equivalent to using an old school ArrayList and you need to re-discover the type information of each element as it's used?
|
# ? Nov 17, 2011 00:19 |
|
Zhentar posted:It's not possible to cast parent to Parent<ICommon> unless T is ICommon. You can only use covariance with interfaces, and even then you shouldn't be able to make something with an Add function covariant. If no one has a solution by tomorrow morning, I should be able to post one up by then. At least, assuming I'm remembering correctly (pretty sure I've dealt with this issue before). (Which, coincidentally, is also the reason I agree that it's a situation that a developer shouldn't have to deal with in the first place, haha...)
|
# ? Nov 17, 2011 00:26 |
|
Ok, I'm a bit lost on the discussion here. Is the child a class that derives from Parent<T>, or are we talking about a child object in a parent object trying to find its parent? If it's the first, why not just add an Add<T> method to Parent<T>? The derived class wouldn't lose the type safety of the T there. If it's the latter, why not have the child raise an event that the parent can listen for? Then the parent can deal with casting the object to whatever T is. Or you can do: code:
Or you can do the fun dynamic way which won't get checked until runtime: code:
PhonyMcRingRing fucked around with this message at 00:42 on Nov 17, 2011 |
# ? Nov 17, 2011 00:27 |
|
This is basically the whole situation http://pastebin.com/E0Fzp0F4Monkeyseesaw posted:So it's a List<ICommon> (or something much like it) which means everything in it is guaranteed to be an ICommon. But then it sounds like the collection contains heterogeneous implementations of ICommon, of which you need to know the actual type (or parent type) after pulling it out of the collection? Am I getting that right? This sounds like a disaster of a design. We have to create and return error files (that give detailed information) so we can't just discard erroneous data while we're initially reading the file in. Basically there are three types of classes to account for; Lists, "Primitives", and "Everything else", and everything is an ICommon. Everything of a specific type is generally identical, except for the specific validations you have to do on them; and in the case of "Everything else" types, they have variable "children" (wrt to a tree) that can be any of the three types (list, primitive, other), but are otherwise identical. I had nothing to do with designing the class structure or file structure that is based off said structure that we read to/from, as mentioned its a 500 y/o industry standard that everyone and their mother uses. I'm just moving it from pseudo-code to C#.
|
# ? Nov 17, 2011 02:13 |
|
Mr. Crow posted:This is basically the whole situation http://pastebin.com/E0Fzp0F4 Can you change the List<ICommon> to a Dictionary<ICommon, ParentType>? That would solve all you problems.
|
# ? Nov 17, 2011 10:07 |
|
Your main problem is this line: ((ListBase<ICommon>) parent).Add(child) [edit] To clarify, the cast is the problem: ((ListBase<ICommon>) parent) The Add(child) is not an issue, because your code throws an InvalidCastException before it even gets there. [/edit] Parent is NOT a ListBase<ICommon>, it's a ListBase<T>, that T is constrained to implement ICommon is irrelevant as ListBase<T> does not derive from ListBase<ICommon>. Since you're using reflection to determine T, there's no really easy way to make that cast work. It can be done by some other fuckery, but that solution would probably be more at home in the coding horrors thread than here. But, like others have already suggested, this should work: code:
code:
code:
code:
Also, if you really need to keep ListBase<T>'s generic parameter, consider adding new() to ListBase<T>'s constraint. Your code already makes the assumption that an instance of T can be created by invoking a parameterless constructor, might as well enforce it. To reiterate, maybe there's some reason in the rest of your code why ListBase needs to be generic, but as far as I can see from this code, you're only unnecessarily complicating things by doing so. Making it non-generic would solve pretty much all of your problems. edit; Another thing: code:
dwazegek fucked around with this message at 10:32 on Nov 17, 2011 |
# ? Nov 17, 2011 10:19 |
|
First off thanks for the help/comments!dwazegek posted:Your main problem is this line: Well I know the cast is the problem, that was the question. Guess I was hoping for to much as far as constraints are concerned and being able to cast; hadn't thought of dynamic though so thanks. quote:Couple of other things: It originally wasn't generic and I recently made it such because I was hoping it would make determining what the items in the list should be significantly easier than just having gigantic if/else blocks everywhere. And as I've said before, the List is <ICommon> instead of <T> to account for the data that we need to keep track of that is completely foreign or otherwise wrong. quote:
Well like I said it originally was. And the ICommon / SUPERBASEWHATSUP thing, ICommon is the version independent representation of a node, SUPERBASEWHATSUP is the most basic representation of a node for a given version. They release a new version of the standard every couple years and the idea is to support every version going forward, rather than just the latest. quote:edit; Same problem as above, can't exactly do is ListBast<ICommon> (which I should ). It's not pretty but either I can have a huge gently caress-off if-statement with every T (of which there are at minimum 30) which I'd have to remember to change if anything else was changed, or I can just key off the field they will all have in common, and only lists have in common. Although I think I've had an epiphany on how to make the whole situation less annoying/terrible and still be able to handle the unknown/incorrect data. Mr. Crow fucked around with this message at 18:16 on Nov 17, 2011 |
# ? Nov 17, 2011 15:51 |
|
Mr. Crow posted:... Can't you just add HasChildren and GetChildren functions to you ICommon interface (or to your base class)? Then your whole GetChildren function could be changed to a simple recursive iterator function: code:
In the case of ListBase<T>, like you've seen, working with generics has the disadvantage that you lose an easily workable base class. You can solve this by inserting a non-generic subclass (adding an interface would work as well). code:
|
# ? Nov 17, 2011 18:29 |
|
dwazegek posted:Can't you just add HasChildren and GetChildren functions to you ICommon interface (or to your base class)? Then your whole GetChildren function could be changed to a simple recursive iterator function: ICommon does actually have a GetChildren method (returns an empty list if there are no concrete children), this GetChildren function is part of a completely separate thing (and in this context is probably misleading). It's basically a rough and ready temporary internal editor I'm making for these files because we need to be able to create "template files" that in the normal business side we would just read in a template file, and then pulling a bunch of crap from the DB update the file as necessary. quote:In the case of ListBase<T>, like you've seen, working with generics has the disadvantage that you lose an easily workable base class. You can solve this by inserting a non-generic subclass (adding an interface would work as well). Yea I'm not sure why I didn't just do that to begin with and it's what I ended up doing (among other things). I think I didn't completely understand generics (well I still don't) and thought it would be an unnecessary layer when I could just as easily call is Parent<> or something. Mr. Crow fucked around with this message at 19:15 on Nov 17, 2011 |
# ? Nov 17, 2011 19:07 |
|
Mr. Crow posted:Yea I'm not sure why I didn't just do that to begin with and it's what I ended up doing (among other things). I think I didn't completely understand generics (well I still don't) and thought it would be an unnecessary layer when I could just as easily call is Parent<> or something.
|
# ? Nov 17, 2011 21:03 |
|
|
# ? Apr 23, 2024 10:17 |
|
I had found it earlier on SO, I assume this is what you mean?code:
|
# ? Nov 17, 2011 21:56 |