Asked  7 Months ago    Answers:  5   Viewed   29 times

In most programming languages, dictionaries are preferred over hashtables. What are the reasons behind that?

 Answers

48

For what it's worth, a Dictionary is (conceptually) a hash table.

If you meant "why do we use the Dictionary<TKey, TValue> class instead of the Hashtable class?", then it's an easy answer: Dictionary<TKey, TValue> is a generic type, Hashtable is not. That means you get type safety with Dictionary<TKey, TValue>, because you can't insert any random object into it, and you don't have to cast the values you take out.

Interestingly, the Dictionary<TKey, TValue> implementation in the .NET Framework is based on the Hashtable, as you can tell from this comment in its source code:

The generic Dictionary was copied from Hashtable's source

Source

Tuesday, June 1, 2021
 
OMGKurtNilsen
answered 7 Months ago
47

Scott Meyers gave a talk about this. This is what I remember:

In C++14 there is nothing useful bind can do that can't also be done with lambdas.

In C++11 however there are some things that can't be done with lambdas:

  1. You can't move the variables while capturing when creating the lambdas. Variables are always captured as lvalues. For bind you can write:

    auto f1 = std::bind(f, 42, _1, std::move(v));
    
  2. Expressions can't be captured, only identifiers can. For bind you can write:

    auto f1 = std::bind(f, 42, _1, a + b);
    
  3. Overloading arguments for function objects. This was already mentioned in the question.

  4. Impossible to perfect-forward arguments

In C++14 all of these possible.

  1. Move example:

    auto f1 = [v = std::move(v)](auto arg) { f(42, arg, std::move(v)); };
    
  2. Expression example:

    auto f1 = [sum = a + b](auto arg) { f(42, arg, sum); };
    
  3. See question

  4. Perfect forwarding: You can write

    auto f1 = [=](auto&& arg) { f(42, std::forward<decltype(arg)>(arg)); };
    

Some disadvantages of bind:

  • Bind binds by name and as a result if you have multiple functions with the same name (overloaded functions) bind doesn't know which one to use. The following example won't compile, while lambdas wouldn't have a problem with it:

    void f(int); void f(char); auto f1 = std::bind(f, _1, 42);
    
  • When using bind functions are less likely to be inlined

On the other hand lambdas might theoretically generate more template code than bind. Since for each lambda you get a unique type. For bind it is only when you have different argument types and a different function (I guess that in practice however it doesn't happen very often that you bind several time with the same arguments and function).

What Jonathan Wakely mentioned in his answer is actually one more reason not to use bind. I can't see why you would want to silently ignore arguments.

Friday, June 4, 2021
 
Corne
answered 7 Months ago
33

WindowsFormsSynchronizationContext works by attaching itself to a special control that is bound to the thread where the context is created.

So

if (foo.InvokeRequired)
{
    foo.BeginInvoke(...)
} else {
    ...
}

Can be replaced with a safer version :

context.Post(delegate
{
    if (foo.IsDisposed) return;
    ...
});

Assuming that context is a WindowsFormsSynchronizationContext created on the same UI thread that foo was.

This version avoid the problem you evoke :

Right after non-GUI thread executes foo.InvokeRequired the state of foo can change. For example, if we close form right after foo.InvokeRequired, but before foo.BeginInvoke, calling foo.BeginInvoke will lead to InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created. This wouldn't happen if we close the form before calling InvokeRequired, because it would be false even when called from non-GUI thread.


Beware of some special cases with WindowsFormsSynchronizationContext.Post if you play with multiple message loops or multiple UI threads :

  • WindowsFormsSynchronizationContext.Post will execute the delegate only if there still is a message pump on the thread where it was created. If there isn't nothing happens and no exception is raised.
    Also if another message pump is later attached to the thread (Via a second call to Application.Run for example) the delegate will execute (It's due to the fact that the system maintain a message queue per thread without any knowledge about the fact that someone is pumping message from it or not)
  • WindowsFormsSynchronizationContext.Send will throw InvalidAsynchronousStateException if the thread it's bound to isn't alive anymore. But if the thread it's bound to is alive and doesn't run a message loop it won't be executed immediately but will still be placed on the message queue and executed if Application.Run is executed again.

None of these cases should execute code unexpectedly if IsDisposed is called on a control that is automatically disposed (Like the main form) as the delegate will immediately exit even if it's executed at an unexpected time.

The dangerous case is calling WindowsFormsSynchronizationContext.Send and considering that the code will be executed: It might not, and there is now way to know if it did anything.


My conclusion would be that WindowsFormsSynchronizationContext is a better solution as long as it's correctly used.

It can create sublte problems in complex cases but common GUI applications with one message loop that live as long as the application itself will always be fine.

Monday, August 16, 2021
 
KMC
answered 4 Months ago
KMC
33

I Try this Trick:

If the user clicks on a row header, change the EditMode to EditOnKeystrokeOrF2and end the edit.

If the user clicks somewhere else, change the EditMode to EditOnEnterand begin the edit.


Private Sub dgv2_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv2.CellClick
    If e.ColumnIndex = -1 Then
       dgv2.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
       dgv2.EndEdit()
    ElseIf dgv2.EditMode <> DataGridViewEditMode.EditOnEnter Then
       dgv2.EditMode = DataGridViewEditMode.EditOnEnter
       dgv2.BeginEdit(False)
    End If
End Sub
Wednesday, November 3, 2021
 
Kyle Vassella
answered 1 Month ago
79

DataGridViewRow.DataBoundItem will give you a dataViewRow for the current item in the Databound dataTable (dataview).

So:

Dim drv as DataRowView = myDataGridViewRow.DataBoundItem

Dim dr as DataRow = drv.Row

Will give you the DataRow from your datagridviewrow.

Saturday, December 4, 2021
 
shivam
answered 2 Days ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share