Tutto e' nato cercando di capire come mai questo codice in C# non funziona se convertito in VB.NET:

        struct test
        {
            public int x;
        }

        static void Main(string[] args)
        {
            test t = new test();
            t.x = 12;
            FieldInfo fi = t.GetType().GetField("x");
            object o = t;
            fi.SetValue(o, 12);
            t = (test)o;
            Console.WriteLine(t.x); //12
        }

il quale non fa altro che settare il campo x della struttura test via reflection...

L'equivalente VB e' il seguente, e _non_ funziona:

    Public Structure test
        Public x As Int32
    End Structure

    Sub Main()
        Dim t As New test
        Dim fi As FieldInfo = t.GetType().GetField("x")
        Dim o As Object = t
        fi.SetValue(o, 12)
        t = DirectCast(o, test)
        Console.WriteLine(t.x)
    End Sub

Il motivo e' dovuto a questa linea: Dim o As Object = t
Infatti mentre in C# equivale all'istruzione IL box, VB la traduce in questo “pseudo IL“:

Dim o as Object=System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(t)

andando percio' ad associare ad o una copia “boxed“ della struttura t.

La controprova e' che mentre se in C# scriviamo:

object o1 = new test();
object o2 = o1;
Console.WriteLine((object.ReferenceEquals(o1, o2))); //True

in VB.NET:
Dim o1 As Object = New test()
Dim o2 As Object = o1
Debug.WriteLine((Object.ReferenceEquals(o1, o2))) '// False

Ovvero SetValue lavora su una copia boxed di test mentre DirectCast (IL alla mano) lavora sempre su t.
Fortunatamente esiste una soluzione per allineare i comportamenti, anziche' dichiarare o as object dichiaratela as ValueType in questo modo l'assegnazione verra' mappata direttamente su box di IL.
Non sono un mago di IL quindi potrei avere detto qualche inesattezza, lascio ad Adrian eventuali approfondimenti...

In questi casi capisco chi e' “ostico“ verso VB.NET...