Problem overriding methods in VB.NET (Error BC30284) - vb.net

I have an overridable sub in my base class
Project1:
Public Class BaseClass
Protected Overridable Sub MySub(ByVal Parameter as MyType)
End Class
Project2:
Public Class DerivedClass
Inherits BaseClass
Protected Overrides Sub MySub(ByVal Parameter as MyType)
End Class
MyType is a type that comes from external COM library. When I'm trying to override it in a derived class, I'm getting
error BC30284: sub 'MySub' cannot be declared 'Overrides' because it does not override a function in a base class
I've added the required COM reference to both projects containing base and derived classes.
Any idea how to get rid of this error? I'm using VS2005 and .NET 2.0
Edit: Every other override is working fine, I'm only getting error if I'm using referenced COM types as parameters. If I change Parameter to Object, overriding works fine.

Have you considered or tried using TlbImp.exe to generate a static DLL from the COM type library, and reference that from both projects (instead of using a COM reference) to make sure they are referring to exactly the same thing? TlbImp is included with Visual Studio, but I can't find it on my system with only Visual Studio Express installed, so if you're using express, you might have to go hunting for it (the linked page may or may not have the version you want). I suspect that if each project has their own COM reference, Visual Studio may be creating a separate COM wrapper for each project and the generated COM wrappers may not entirely agree with each other when it comes to generated GUIDs and whatnot. So by creating a and forcing the use of a single wrapper you may be able to eliminate that as a possible problem.

Rather than using TlbImp, another option is to have a separate project where you encapsulate the MyType in a .NET class and include that project in both your samples.
So you would end up with an intermediate MyDotNetType which would take as a constructor argument Mytype (the COM object) and expose it out as a read-only property.
Then the MySub call, would take the MyDotNetType as an argument.
Kind Regards
Noel

Please check the signature of the Function in both base class and derived class, if you have different agruments or data type o any arguments is not matched. Then you'll get this type of error. Simple please check the function name, argument name and data type. It worked me. I hope this answer will be helpful.
Thanks,
Ramu V

Related

What is the use of Module in VB.Net programming?

I am creating a .dll for a CAD tool I use.
After creating a new project (class library) , I got a "public class-end class" block.
I wrote my main method inside that block. When I run the dll in my CAD tool, its giving me main entry point missing error.
So i come back and change the "public class-end class" ---> "Public Module-end Module".
Now its able to find the main method.
Why is this so? Ive read on these forums that we should not be using modules as much.
If I were to not use modules so much, how I am supposed to make it work without the module block?
VB.Net doesn't have static classes like C# has. Static classes allow you to create static methods such that
class foo
{
void bar() {}
}
Accessed in VB.Net like this
foo.bar()
If you want to create the same functionality with VB.Net you have two options, which are either using a Module
Module foo1
Sub bar()
End Sub
End Module
Class foo2
Shared Sub bar()
End Sub
End Class
However the difference is how Module and Class are scoped. Modules are globally scoped so you can call the module method outside of the originating namespace without qualifying it with the Module name, but to call the static method you need to qualify it with the class name, and even import the namespace in the case of a class with static method
bar()
foo2.bar()
But what Modules are certainly good for is Extension Methods, and the global scope actually helps here if you want to extend a class across your project
Module Extensions
<Extension>
Sub bar(value As String)
End Sub
End Module
Dim s = "my string"
s.bar()
In your case, it's expecting a C# style static class with method, and since VB.Net doesn't have static classes, a Module or class with static method both satisfy that.
Modules come from legacy versions of Visual Basic and sort of act as the "OG" of Visual Basic code files. When Visual Basic 6 and earlier was around, Visual Basic was sort of quasi object oriented and while classes existed, it made more sense to use modules in lieu of static classes. Then when Visual Basic .NET was introduced, Microsoft made a real effort to make the programming language a true object oriented programming language.
People likely tell you to use classes over modules because modules are holdovers from the days prior to Visual Basic being a pure object oriented language. Starting from 2005 on forward, anything you could do in a module could basically be done as a static (aka shared) only class with the exception of extension methods. So by using classes over modules, you're taking a more .NET oriented approach rather than a Visual Basic first approach.
With regards to your specific problem, the issue is that your CAD tool is looking for an entry method, but cannot find one. The simple solution is to add a shared method:
Public Class MyClass
Public Shared Sub Main()
' ...
End Sub
End Class

Permission class in vb.net

creating an assembly named Assembly1. Assembly1 contains a public method.
The global cache contains a second assembly named Assembly2. You must ensure that
the public method is only called from Assembly2. Which permission class should you use?
It is impossible to say "method can be used only by Assembly2". But, if I understood you correctly and your goal is to prevent calls from any other assembly, except for Assembly1 or Assembly2, I have an answer.
In .NET you can do this using some trick. You can make your public method Friend (can be used only by Assembly1). And then use Friendly Assembly mechanism. After that you will have method that could be called only from Assembly1 or Assembly2.

Parameterless constructor in Structure

Following on from this question on using different Visual Basic versions in Visual Studio 2015, I'm running through the new lanugage features in Visual Basic 14, as documented here and here.
One of those is the ability to have parameterless constructors in structures, like this:
Structure MyStruct1
Public f As Integer
Sub New()
f = 15
End Sub
End Structure
When I try this in code in Visual Studio 2015, I'm still getting an red error squiggle under the New():
BC30629 Structures cannot declare a non-shared 'Sub New' with no parameters.
I haven't seen anywhere that states that this got pulled before release.
Am I mis-understanding what this new feature does?
As you can see in the quoted text below, Roslyn removed support for structures with parameterless constructors, and therefore it's not listed as a new feature in VB 14.
It has been a long standing requirement that C# and VB struct
constructors would always have parameters. We have tried to relax this
requirements in C#6.0 to make structs more consistent with classes.
While overall parameterless constructors in structs are valid from IL
perspective, without a convenient way to declare them they were
virtually nonexistent. As we performed more and more testing, we kept
discovering cases where parameterless struct constructors caused
inconsistent behavior in libraries or even in some versions of CLR.
A good example is the issue reported in the CodePlex bug http://roslyn.codeplex.com/workitem/465. The issue is basically an
optimization introduced in Activator.CreateInstance around CLR 4.0 and
present ever since. The optimization assumes that parameterless
instantiation of generic T type does not cause sideeffects if T is
found to be a struct and therefore instances can be cached.
Parameterless struct constructors would violate such assumptions and
make optimization observable, thus necessitating servicing of existing
code several versions back.
After reconsidering the potential issues arising from breaking long
standing assumptions, we decided it was best for our users to restore
the requirement on struct constructors to always have formal
parameters.
Source: Restore requirement for struct constructors to always have formal parameters. #1029
You need to use Shared Keyword(acts as static) for a Parameter less Constructor in VB.Net.
Try the code below:
Structure MyStruct1
Public Shared f As Integer
Shared Sub New()
f = 15
End Sub
End Structure
Class My_Class
Public Shared Sub Main()
Dim str1 As New MyStruct1()
End Sub
End Class
Note: Shared keyword here acts as static. While using a Shared Constructor you need to access Shared variables, that is why I have declared the variable with Shared keyword.

Use of VB.NET class in VB6 via interop requires class to have constructor?

When I try to create a VB.NET object via interop in VB6, I have noticed I get this error if my VB.NET class doesn't have a constructor:
Error 430 - Class doesn't support automation
All I have to do is put an empty constructor in the VB.NET class, eg:
Public Sub New()
End Sub
and the error is avoided. Is this the expected behaviour?
VB6 creates objects through COM, using the class factory for a COM coclass. The underlying method is IClassFactory::CreateInstance(). This method does not permit passing any arguments to the factory. It therefore follows that the [ComVisible] .NET class must have a constructor that doesn't take any arguments.
.NET already creates a default constructor for a class, unless you specify a constructor yourself that takes arguments. Which will never be used, you might as well remove it. Now you also don't need the empty default constructor anymore.

C++ virtual (sealed) function

I am using classes from a dll in my C++ project. All is working fine, until...
When trying to call a certain method (listed in the object browser), I am getting an error that this method is not a member of the namespace.
Upon investigation, I noticed that this method is listed as "virtual void x() sealed".
Is there a way to make a call to such a function?
For future reference, I just received a response from the enterprise library support team. They posted a link to the following:
Managed C++ and IDisposable
I'm writing some code using the new Managed C++/CLI syntax and I ran into this error:
error C2039: 'Dispose' : is not a member of 'System::IDisposable'
the code I started with was this:
image->Dispose(); // image implements IDisposable
which gave me the same compiler error, so I wanted to eliminate a class/namespace error so I rewrote it as this:
((IDisposable ^)image)->Dispose();
Which gave the above error. Yikes!
Here's the fix:
use delete. Managed C++ now hides Dispose() inside the finalizer. Just delete the object, it handles the rest. Freaky.
This really works!!!!
Sealed in a C++ CLI keyword (managed C++) specific to .NET and not C++ in general.
sealed on a function means that you can't override that method in a derived type.
sealed does not mean that you can't call the function, I'm guessing your function is private.
I don't see why it being virtual and sealed should in itself prevent you from calling the function. According to MSDN, the sealed keyword is specifically meant for virtual methods anyway.
Is there any more information you can give about the function in question and how you are trying to use it?