|
So I'm quite comfortable with shallow and deep cloning for value and reference types but want to check how this plays out for an array of a value type.
I have a 2D array of double and since the array contains value types I think the Array.Clone method (whilst only guaranteeing shallow copies) will give a deep copy in this instance. Am I right?
Private _matrix as double(,)
Public Function CopyToArray() as Double(,)
Return Me._matrix.Clone()
End Fucntion
Public Function Copy() As Matrix
Return New Matrix(Me.CopyToArray())
End Function
Public Sub New(ByVal array As Double(,))
Me._matrix = array
End Sub
The constructor assumes that the user wants to assign the 2D array of double(,) they have already created to the new matrix instance and hence doesn't use Array.Clone (and since the array is a class and is therefore a reference type, ByVal essentially has no meaning in this context). Did I get that bit right?
Thanks,
Mike
|
|
|
|
|
It will copy the values. Now tell me, is that shallow or deep?
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: Now tell me, is that shallow or deep?
Taking the question seiously for a moment, for copy/clone of value types or arrays of a value type, shallow == deep. For reference types, copy/clone shallow != deep.
So, last question, since an array is a reference type then there's a vast difference between these two alternatives:
Private _matrix as double(,)
Public Sub New(ByVal array As Double(,))
Me._matrix = array
End Sub
and
Private _matrix as double(,)
Public Sub New(ByVal array As Double(,))
Me._matrix = array.Clone
End Sub
Whereas with an array of reference types there would only be a subtle difference?
Mike
|
|
|
|
|
Mike-MadBadger wrote: for copy/clone of value types or arrays of a value type, shallow == deep
Mike-MadBadger wrote:
Private _matrix as double(,)
Public Sub New(ByVal array As Double(,))
Me._matrix = array
End Sub
Would assign the pointer to the array to "Me._matrix". (Both in case of value- and reference types)
Mike-MadBadger wrote:
Private _matrix as double(,)
Public Sub New(ByVal array As Double(,))
Me._matrix = array.Clone
End Sub
Would create a copy of the values (shallow, again for value and reference-types)
Mike-MadBadger wrote: Whereas with an array of reference types there would only be a subtle difference?
In the case of value-types, the result would be identical; you'd end up with an array of values. For reference-types, it'd be similar; version one assigns a pointer to the array, version two copies the structure of the array (and thus, all pointers to references it contains) and you end up with an exact copy of the list, still pointing to the original objects.
A shallow copy of an Array copies only the elements of the Array, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new Array point to the same objects that the references in the original Array point to.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Apologies for the delay, been busy leaving work ready to move to a new country !!
I think we are absolutely agreeing but saying it in different ways, so for clarity I wanted to check this comment:
Eddy Vluggen wrote: In the case of value-types, the result would be identical; you'd end up with an array of values.
I don't understand the identical bit. In the first case you have a pointer to an existing instance of an array in the second case you create a new instance of an array with the same structure as the one you cloned? Perhaps pedantry but in this case, at least for understanding, forgiveable pedantry I feel...
That's what leads to clarity over the value / reference difference.
In the value case the new array structure contains new, independent value 'objects'.
Whereas in the reference case the new array structure contains new, independent pointers to the same object instances that the pointers in the original array pointed to.
Mike
|
|
|
|
|
Mike-MadBadger wrote: been busy leaving work ready to move to a new country !!
Getting ready for adventure? From where to where?
Mike-MadBadger wrote: I don't understand the identical bit. [..] Perhaps pedantry but in this case, at least for understanding, forgiveable pedantry I feel...
It's not pedantry, but being precise.
Mike-MadBadger wrote: In the first case you have a pointer to an existing instance of an array in the second case you create a new instance of an array with the same structure as the one you cloned?
Exactly
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Eddy Vluggen wrote: Getting ready for adventure? From where to where?
UK (Reading) to France (Lyon).
Same industry, different company, family et al in tow. It certainly will be an adventure. Thanks for asking.
|
|
|
|
|
Good luck and enjoy
|
|
|
|
|
As to whether that difference is *important*... well, that completely depends on what you do with them.
Say you have a User object and this involves the concept of a list of Favourites (products, girls, doesn't matter). It'd probably be a List<Favourite> rather than a Favourite[], but no matter. The point is if for some reason you wanted to let one user copy another user's favourites, what should you do? Just point to the same list? Or make an actual copy of the list? Surely you should copy it, that way if user A subsequently edits his copy, the other one is not affected.
What about the Product objects themselves? Well, there's no need to clone them unless they "belong" to the user. If they are shared, you could happily point to the same Products, and both users would see any changes to products they have in their respective lists.
--
I know this isn't the right forum for it, but I gotta ask: Are you really from Hell, Eddy? A lot of English speakers claim they're from Hell, but most of them don't even know where it is! Look up "Hell, Stjørdal, Norway" on Google Maps, and you won't be one of them.
It depends. It *always* depends.
|
|
|
|
|
dojohansen wrote: The point is if for some reason you wanted to let one user copy another user's favourites, what should you do? Just point to the same list?
I'd serialize the list, as the user won't be sharing my PC's memory The most obvious route would be XML.
dojohansen wrote: I know this isn't the right forum for it, but I gotta ask: Are you really from Hell, Eddy?
It *depends*; if you mean the physical Hell from Norway, I hope to spend my old age there. Not only is it a very low-populated area, one also gets a 6-month night! I heard that one can even get there by train, and internet can probably be arranged too
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Hi everyone. I have picked up some great tips and tricks from this website and as a consequence I have pretty much finished my desktop SMS project.
I have asked this question in the .net section as my project is written in such. However, my question is more about the possibilities and practicalities of SMS forwarding as there seems to be a few experts on the general subject here.
my .net project can send and receive SMS text messages through most GSM modems attached to the PC via usb or bluetooth. These text messages are then inserted into SQLServerCe database where certain actions are performed on the messages.
However, I now have a problem. I have seen a a program called SMS Enabler which has the function for setting up a forwarding number. At first I thought it was just a case of taking the received message and then automatically resending it to a stated number.
However, this is not the case as by doing that you are incurring the cost of that SMS as you would for any SMS sent.
This software will forward your SMS to the stated number at no extra cost. I could be wrong, but this might be called "bouncing" the sms onwards. Perhaps it works a bit like call forwarding?
Does anyone know how this might be achieved where an SMS is received by the software and then is auto forwarded to another number at no extra cost (except perhaps to the sender)?
A description of the forwarding by the aforementioned software can be found here: http://smsenabler.com/forward-incoming-sms-to-another-number.html[^]
Many thanks for your help.
|
|
|
|
|
Hi,
I'm using Visual Studio and ASP to generate a web page. On it is a Gridview with several columns. I want to have access from JavaScript to change data client-side in one of those (non-key) columns. So I used:
<asp:TemplateField HeaderText="Percentages">
<ItemTemplate>
<asp:Label ID="PERCSIT" runat="server"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="PERCS" runat="server" Text='Even geduld a.u.b.'></asp:TextBox>
</EditItemTemplate>
<ControlStyle BackColor="#00CC00" Width="35px" />
</asp:TemplateField>
However, when this is rendered, no ID is generated since it is neither a data-bound nor a key column, just a <td> tag.
So my question is: is there a way to force the rendering to generate an ID anyway, so it can be manipulated from JS?
Thanks in advance,
Jur.
modified 5-Oct-12 10:34am.
|
|
|
|
|
AtALossHere wrote: when this is rendered, no ID is generated sin
ID of what? Every control would have an ID so that you can access it on client side. The snippet shared above has two controls and I see ID defined for both of them.
Please add ID at the time of placing controls and you can access column value associated with that control at runtime.
|
|
|
|
|
No, it isn't... when this is rendered, it just generates [td]Even geduld a.u.b.[/td] (the text assigned design-time) and nothing else...
|
|
|
|
|
Once again, you are expecting an ID for which control?
Grid converted in to a Table and ID's of its rows and columns? If so, why is it needed? You need controls ID's in them.
|
|
|
|
|
I'm expecting ID's for each of the row's labels. These are looked up server-side with
ClientScriptManager cs = Page.ClientScript;
foreach (GridViewRow gvr in GridView2.Rows)
{
Label lb3 = ((Label) gvr.FindControl("PERCS"));
cs.RegisterArrayDeclaration("PERCIDs", String.Concat("'", lb3.ClientID, "'"));
so the JavaScript can edit values with
x = document.getElementById(PERCIDs[i]);
x.value = "Assigned client side";
However, the
Label lb3 = ((Label) gvr.FindControl("PERCS"));
returns null because, browsing the generated page source, no ID is generated.
|
|
|
|
|
Sigh. Finally found the answer. If someone ever has a similar problem and finds this thread, this is what caused it for me.
In another piece of server code (the RowDataBound of the Gridview), this field was explicitly changed.
e.Row.Cells[PercentageKolomNummer].Text = cPercs;
It appears that, by doing this, the rendering "forgets" that it is a label and doesn't generate the ID for the label. By removing the assignment, the ID is generated and FindControl can find it again.
|
|
|
|
|
I'm trying to get my head around a good way to set up exception management in a custom class, if I understand some of the advice in CP articles and elsewhere correctly then something like this setup is 'a' good way:
Simplified case: A class encapsulates a 2D array and has an UpperBound property that takes a an integer and returns the UpperBound of that dimension (since it does not expose the array directly).
Rather than the UpperBound property testing that the integer is either 0 or 1, I should put the call to the array GetUpperBound(dimension) method in a Try block and catch the exceptions that can be thrown by the array method, then re-throw the exception from the encapsulating class with the array exception as the inner exception parameter. Is that smart?
Then if another method in the class uses the UpperBound property (in the encapsulating class) it should catch and re-throw the exceptions created by the UpperBound method (again with the inner exception as a parmater), hence the exception the programmer recieves has a trail directly from the methods they called through whatever path was then followed and ending up with the base exception thrown by the encapculated array.
For example:
Public ReadOnly Property UpperBound(ByVal dimension As Integer) As Integer
Get
Try
Return Me._matrix.GetUpperBound(dimension)
Catch inex As IndexOutOfRangeException
Throw New IndexOutOfRangeException("The dimension you specified is out of range for this matrix object. Matrix objects have only two dimensions, 0 and 1. See the inner exception for more detail.", inex)
Catch ex As Exception
Throw
End Try
End Get
End Property
Then if I had another method in my class (call it Iterate for example) that needed the UpperBound of the rows (dimension = 0), say to use in a For loop, it would again do this in a Try block, call the UpperBound property and catch the exceptions thrown by the UpperBound property. So if somehow this latter method (Iterate) managed to make a call to UpperBound(2) then the programmer would see the Iterate method throw an IndexOutOfRange exception with the UpperBound exception as its inner exception and that in turn would have the array GertUpperBound exception as an inner exception.
Smart, dumb - other names? Advice?
Mike
|
|
|
|
|
As long as your catching the exception adds value, then it's fine for you to catch it, add detail and then pass it back up the chain. A big note, in your sample though, you catch and throw the general purpose exception for no reason - as you are only interested in the IndexOutOfRangeException , that's the only one you should be catching there.
|
|
|
|
|
Thanks, Pete. In terms of adding value I am assuming that an exception raised by a method that you didn't call is harder to trace / debug, whereas if you have the full history then it should start with the method you called and you can then trace back to where that call went and probably have a better idea of where it went wrong - i.e. there's no apparent direct benefit of what I am doing in this (and most) cases other than tracing exceptions.
Pete O'Hanlon wrote: in your sample though, you catch and throw the general purpose exception for no reason That's something I saw in one of the CP articles (I think I interpreted it from this one[^]). I had read into it that what I am doing is saying that if anything I wasn't expecting happens, just re-throw the same thing to ensure you don't lose it, i.e. it's a side effect of a Try block. Maybe I assumed that without it I would in effect be 'swallowing' all other exceptions, but maybe that only happens if I catch the general purpose one and then leave the catch block empty?
Does your comment mean that it is redundant - i.e. is that what would have happended anyway, even without that last catch statement?
Thanks,
Mike
|
|
|
|
|
Mike-MadBadger wrote: I had read into it that what I am doing is saying that if anything I wasn't
expecting happens, just re-throw the same thing to ensure you don't lose it,
i.e. it's a side effect of a Try block. Maybe I assumed that without it I would
in effect be 'swallowing' all other exceptions, but maybe that only happens if I
catch the general purpose one and then leave the catch block empty?
Actually, what I was referring to was don't bother catching it at all. When you catch and throw, without doing anything with the exception, it's a waste of time. So, in your case, all you needed to catch was the IndexOutOfRangeException . Any other exception is still going to show your method in the stack trace, so there is still context there for you to work with.
I hope that explains it better.
|
|
|
|
|
I am thinking of an app (C# windows app ) as it just needs to be started once - it must itself stand and loop - so it detects when there are new images also the to run automatically afterwards. Please enlighten me some ideas I will be ever so grateful.
PS. I am using Visual Studio 2010
Kind Regards
JG
|
|
|
|
|
This makes very little sense as it stands right now. I'm sure that you have a great understanding of what you want your application to do, but sadly, you haven't managed to convey it. For instance, what does it need to run automatically?
As far as monitoring for new images, take a look at the FileSystemWatcher , but be aware that there are some limitations with it that you need to understand based around when it fires events.
|
|
|
|
|
Well I am sorry for not being very clear, the scenario is like this, I get a number of HDR pictures in a folder, I have a program which batches these images and put them out in different folders, This particular program can also be used with command-line, So what I am trying to do is create an windows app, where I want to use this particular command, so all the images go in a single folder. Therefore I want construct this app where once I have started it giving it a source, it should keep running and once new images arrive it just simply updates. I don't know if it's clear enough or its simple not logical.
|
|
|
|
|
Okay, some things to think of - you will want to put your processing on background thread, I would recommend using the Task Parallel Library for this as it's so easy to use. I'm not clear on whether you are moving the original image, or copying them - if you are copying them, then move them into a processed folder as soon as you are finished.
|
|
|
|
|