views:

215

answers:

4

I was recently asked a weird question in an interview here it is;

Private Function sorttable  (ByVal dt As DataTable, ByVal sorttype$, ByVal sort_direction$) As DataTable 
         Dim dv As DataView  
         Dim dt2 As DataTable  
         dt2 = dt.Clone  
         dt2.Merge(dt)  
         dv = dt2.DefaultView  
         dv.Sort = sorttype & " " & sort_direction  
         Return dv.ToTable()  
End Function

well this function works sorts correctly but there is a problem about it(well at least the interviewer claimed). Well I couldn't figure out what it was.Any ideas?

+1  A: 

I've never used the DataView orDataTable, but the code doesn't dispose the objects.

Chris Diver
Datatable and dataview objects can be disposed I think.
hrrrr
Yes they can, i checked, but they are not disposed in the code sample you provided. Which could be the answer the interviewer was looking for, unless there is some obvious usage problem.
Chris Diver
It's doubling up the datatable provided - that's the main problem
PostMan
Just had a look at the docs, that code makes no sense. Clone the object then use the merge method. I'd still argue that disposing the objects is a bigger issue.
Chris Diver
But if you see my code, they use who calls this method may dispose of the DataTable passed in, becuase it wasn't created in the method, it would be bad to dispose of it there. IMO
PostMan
What if the reason that the object is cloned, is so that it change doesn't effect the DataView of the DataTable passed, you have changed the way it works.
Chris Diver
Dispose isn't necessary. I don't think there are any unmanaged resources that need to be garbage collected in the DataTable. The CLR will take care of garbage collecting any objects once they fall out of scope.
0A0D
Then why does it have a Dispose method (implement IDisposable)?
Chris Diver
datatable is finalizable so dispose must be called as far as i knowmore info about it in here:http://stackoverflow.com/questions/913228/should-i-dispose-dataset-and-datatable
hrrrr
@Chris: The dispose in most classes is to make it your able to override it and with that to make it you possible to finalize unmanaged resources. The dispose is probably in 80% of the mostly used classes. That does not mean that you **should** use it. (It is in 20% of the actual classes). The garbage collector will call Dispose on each object it is about to collect if that object implements the IDispose interface, togive it one last chance to clean itself up. Dispose itself does not force the object to be garbage collected.
0A0D
@hrrrr: The DataTable does not need Dispose called explictly.
0A0D
A: 

Edit: Merge only copies scheme, not rows. That's why you need it.

Only two problems I see is the Merge and redundant variables (dt2). Since they are passed by value, there is no reason to make extra local copies and create more room for bugs. This is known as a code smell. Also, why merge when you just created a clone of the original data table that already contains the constraints and schema ? It's like doubling up.

0A0D
It is a reference type passed by value, `dt` is not a copy of the original object.
Chris Diver
@Chris: This is wrong - see here: http://www.yoda.arachsys.com/csharp/parameters.htmlA new storage location is created when you pass the DataTable as opposed ByRef. Reference type just means there is a form of indirection between the variable and the actual value
0A0D
@0A0D - doesn't that article prove my point? "Remember though that the value of a reference type variable is the reference - if two reference type variables refer to the same object, then changes to the data in that object will be seen via both variables."
Chris Diver
@Chris: No because if you call dt = null, it doesn't make the original dt null unless you are ByRef
0A0D
Yes, but you are only creating a copy of the reference, not the underlying object. By manipulating dt you are changing the dt outside of the function, so it is not a copy. Which is why the clone statement might be relevant?
Chris Diver
@Chris: Yes, you are correct. Most people don't understand that.
0A0D
@0A0D After clone we dont have any DataRows, thats why we need to Merge, in this case the memeber Copy should be used.
Vash
@Vash: Thanks. Why not use ImportRow?
0A0D
We can use ImportRow, but this is and additiona iteration and i thik that merge is faster ;-).
Vash
@Vash: I ran some tests on the assumption that Merge is faster. In my tests, most of the time ImportRow was slightly slower (100-200 milliseconds) with a 100,000 row DataTable. In some instances, the Merge and ImportRow achieved the same speed though it happened on less occasions.
0A0D
+1  A: 

You're creating DataTables for no reason.

You can use this code to provide the same result

Private Function sorttable  (ByVal dt As DataTable, ByVal sorttype$, ByVal sort_direction$) As DataTable  
         Dim dv As DataView   
         dv = dt.DefaultView   
         dv.Sort = sorttype & " " & sort_direction   
         Return dv.ToTable()   
End Function 
PostMan
hmmmm I think you are right
hrrrr
after rechecking it clone just copies the structure of the data not datatable's data merge copies the data
hrrrr
Fixed to remove this, however the extra datatables were still not needed
PostMan
One downside to this - You're effectively mutating the `dt` parameter, but changing it's `DefaultView`. `DefaultView` is an intrinsic property of the `DataTable`. Modifying this directly could have unintended side-effects.
Nathan Ernst
A: 

I was creaing such nice answer but my FF has crashed...

so in few words..

But what is going there

  • DataTable - Represents one table of in-memory data.

    • Clone - Clones the structure of the DataTable, including all DataTable schemas and constraints.

    • Merge(DataTable dataTable) - This member is overloaded. For complete information about this member, including syntax, usage, and examples, click a name in the overload list.

    • DefaultView - Gets a customized view of the table that may include a filtered view, or a cursor position.

  • DataView - Represents a databindable, customized view of a DataTable for sorting, filtering, searching, editing, and navigation.

    • Sort - Gets or sets the sort column or columns, and sort order for the DataView. Sort string structure - "A string that contains the column name followed by "ASC" (ascending) or "DESC" (descending). Columns are sorted ascending by default. Multiple columns can be separated by commas." The method Clone work almost the same as Copy, the only differance is that the new DataTable created by the Clone method does not contain any DataRows.

The redundation that You have in middtime accepted as good answer, in some cases can be resonable for example we want only sorted copy of those data for other purpose. But there is no need to Clone and then merge, member Copy will do the same.

I'm not a expert but the property Sort of DataView sorts the DataView as we return the DataTable so we do not sorted anything.

Vash