See the question and my original answer on StackOverflow

The VBScript class is not a full COM object because it has no IID (interface ID) associated with it. So, I may be wrong, but I don't think you can have it match a .NET class or interface (many attributes such as ComImport expect an associated Guid attribute). It could work if Foo was created from a "real" COM object. In the background, I believe the VBScript's Foo object implements IDispatch only, so it's by nature very dynamic.

However, you can still use its properties and metods quite easily with the c# dynamic pseudo-type keyword, for example, the following code should work fine:

[ComVisible(true)]
[Guid("9F2B6958-742F-4E5D-A5F3-D6BDC6C841DB")]
[ProgId("COMTests.Class1")]
public class Class1
{
    public void M(dynamic foo)
    {
        Console.WriteLine("foo:" + foo.i);
    }
}

PS: You do not need the interface or the ref attribute in this context. With my code above, this is what will get created automatically by .NET (in IDL terms, a bit simplified for readability):

[
  uuid(E66DC08B-A63A-41A8-B63D-15ED6F4569AB),
  version(1.0),
]
library ClassLibrary1
{
    interface _Class1;

    [
      uuid(9F2B6958-742F-4E5D-A5F3-D6BDC6C841DB),
      version(1.0),
    ]
    coclass Class1 {
        [default] interface _Class1;
        interface _Object;
    };

    [
      odl,
      uuid(F56AF0FC-D93B-399E-8FBD-9B72CF50D7D9),
      hidden,
      dual,
      oleautomation,
    ]
    interface _Class1 : IDispatch {
    };
};