So what does this mean and how do I fix it?
This message occurs if I place the New keyword in the line(s) below. If I remove it, i get an error at runtime saying I need to use New. What am I doing wrong?
Dim oPS As AeccPointStyle = New AeccPointStyle
ops = oDescKey.PointStyle
Debug.Print(oPS.Name)
Debug.Print(oPS.MarkerSymbolName)
Also tried
Dim oPS As New AeccPointStyle
ops = oDescKey.PointStyle
Debug.Print(oPS.Name)
Debug.Print(oPS.MarkerSymbolName)
Thanks!
Update 1 - based on comment from Meta-Knight
1 -
Dim oPS As AeccPointStyle = Nothing
oPS = oDescKey.PointStyle
2 -
Dim oPS As AeccPointStyle = oDescKey.PointStyle
Both versions throw NullReferenceExceptions.
The empty constructor of AeccPointStyle is marked as friend, which means only classes inside its assembly can call it.
But looking at your code, I don't think you need to call New. Just set it to Nothing at first. Or even better, directly set your variable with the good value:
Dim oPS As AeccPointStyle = oDescKey.PointStyle
Edit about your NullReferenceException:
Typically, this type of exception is raised when you call a property of an object with a value of Nothing. In this case, if oDescKey was set to Nothing, such an exception would be raised.
If oDescKey does NOT have a value of Nothing, then the only thing that executes some code is the PointStyle property. So it's safe to assume that the PointStyle property throws a NullReferenceException. Try watching the oDescKey.PointStyle variable in the debugger, you should see that it throws an exception.
If your AeccPointStyle class is using a 'Friend' modifier,
ie it is defined as:
Friend Class AeccPointStyle
or the default constructor has the 'Friend' modifier,
ie:
Friend Sub New()
and the code you posted is not in the same assembly, you cannot call the constructor on this class. In order to get this to work, you must put your code in the same assembly as the AeccPointStyle class. Check out this page to learn more about the modifiers: more information about modifiers
My guess is the following: AeccPointStyle is declared in another assembly than the code sample in your question. The constructor (Sub New) of AeccPointStyle is declared a Friend, which means that it is reachable only within the same assembly.
You can solve this in two ways
Change Sub New so that it is Public
Provide a Shared Public Sub Create, that will create and return a new AeccPointStyle
AeccPointStyle doesn't have a public default constructor. The one you're trying to use is limited to other classes within the same assembly.
Here's some code I found online:
Dim oPointStyle As AeccPointStyle
Set oPointStyle = g_oAeccDoc.PointStyles.Add(strName)
Notice the PointStyles property (probably some sort of PointStylesColleciton) on g_oAeccDoc is instantiating and returning a new AeccPointStyle instance for you.
When using FRIEND as access modifier for your class, you need to make sure that both the class it-self and the class where you use it are in the same NAMESPACE, otherwise you will get this error message.
For other people encountering this issue, I had to do a one-way upgrade for an old project we were referencing. It upgraded it to .NET 4.0 as well, when it was 2.0/3.5. That caused the (also old) project that was an older version to get this error when referencing it. Changing the newly upgraded version back to .NET 3.5 did the trick for me. It's a very non-descript error!
Related
I am building a small helper to fetch and populate all the controls of a ribbon group inside a collection.
Option Strict On
Imports Microsoft.Office.Tools.Ribbon
Private Function GetChildControls(Group As RibbonGroup) As IEnumerable(Of RibbonControl)
Dim ChildControls As New List(Of RibbonControl)
Dim SubControls As IEnumerable(Of RibbonControl) = Group.Items
ChildControls.AddRange(SubControls)
' ...
' Some recursive call over SubControls to get the children of each child (not relevant here)
' ...
Return ChildControls
End Function
Code breaks at ChildControls.AddRange(SubControls), with the following exception:
System.InvalidCastException: 'Unable to cast object of type Microsoft.Office.Tools.Ribbon.RibbonControl[]' to type Microsoft.Office.Tools.Ribbon.RibbonControlImpl[]'.'
I cannot find any reference at all on RibbonControlImpl. The Microsoft documentation is silent, and - surprisingly - so are Google or StackOverflow.
Changing ChildControls.AddRange(SubControls) into SubControls.ToList.ForEach(Sub(p) ChildControls.Add(p)) does not work either, but a classic For Each does the trick:
For Each MySubControl As RibbonControl In SubControls
ChildControls.Add(MySubControl)
Next
I would like to understand what is happening here? Is Impl a suffix to interface types to signify something? Maybe 'Impl' stands for 'Implementation'? I could not find any information on this either.
Just some thoughts, no idea if I am right; what do you think?
Office.Ribbon.RibbonControl is an interop interface, hence cannot be used as a generic type across assemblies. A guess would be that Microsoft implemented a non-interop RibbonControlImp wrapper to which RibbonControl is implicitly cast every time it is referenced as a generic type.
No idea how this would be achieved, but that would explain why For Each ... Next does not throw the error, whilst relying on generic collections does.
Have the following trivial code:
Class A
Private value As Integer = 1
Sub Action(Optional param1 As Integer = value)
End Sub
End Class
Visual Studio complains about default value (value) with error BC30369:
Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.
Is this really the right error for this case? The method is not shared.
In Visual Studio 2012 or 2013, the error in the same case is
Constant expression is required.
what absolutely makes sense.
After additional research I think that there is a problem in order of checks made by compiler.
If I change the code, making value member Shared, I get correct result: Error BC30059
Constant expression is required.
Since nothing except constants can be placed into default value of Optional clause, check for the above BC30059 ("Constant expression is required.") should be obviously made "earlier" than the check for BC30369 (shown in question).
I created bug report at Microsoft Connect.
While trying to access the methodptr property of a delegate object, I am getting the error:
"System.Delegate._methodPtr' is not accessible in this context because it is 'Friend'
,is there some method through which I can access this value and assign it to a variable?
is there some method through which I can access this value and assign it to a variable?
You can use reflection1 to retrieve the value. However, you probably don’t want to do this: this value is Friend for a reason. It’s an implementation detail and you as a consumer of the framework have no right to access it directly: it may work, or it may break suddenly (e.g. when Microsoft distributes an update of the library). Your code also won’t work on alternative .NET implementations, such as Mono.
In particular, this member is not documented in the MSDN and as such its presence or behaviour can’t be relied on.
1 The following should do the trick:
Dim delegateType = yourDelegateObject.GetType()
Dim field = delegateType.GetField("_methodPtr", _
BindingFlags.Instance Or BindingFlags.NonPublic)
Dim methodPtr = DirectCast(field.GetValue(yourDelegateObject), IntPtr)
Untested, since I only have Mono and (as mentioned above) it won’t work here anyway.
I have inheritance structure: Foo implements IGraphNode inherits IGraphItem.
Foo, IGraphItem/IGraphNode, and the implementation for IGraphItem/IGraphNode all reside in separate assemblies. I am using an inversion of control container, so the project I'm working in has a reference to the first two (Foo and IGraphItem/IGraphNode), but not the implementation of IGraphItem/IGraphNode. I also have Option Strict on as it is required for this project (turning if off didn't fix the problem). I'm using .NET 3.5.
I am passing a IGraphItem around and I have code that looks like this:
Public Sub ProcessItem(of IGraphItem)(item As IGraphItem)
If TypeOf item Is Foo Then
Dim f1 = CType(item, Foo) 'Compiler error
Dim f2 = DirectCast(item, Foo) 'Compiler error
'This is what I'm currently having to do. It works.
Dim f = CType(CType(item, IGraphNode), Foo)
'Do stuff
End If
End Sub
Any idea why I'm having to do this? I should add that TryCast works, but since we've just confirmed that item's type is Foo, I don't see why I can't DirectCast it. Shouldn't it just let me and throw an exception if I'm wrong? Is there a better way to accomplish what I'm trying to do?
Your original code compiles without a problem, even when target framework is 3.5.
The problem with your current code is that you've defined a generic method whereas IGraphItem is not the type of your interface but the generic type T which can be any type. But it cannot be another type than T and you're trying to cast it to type Foo.
If you would change your method signature to anything else it would work, for instance:
Public Sub ProcessItem(of IGraphItm)(item As IGraphItem)
I assume that you're somehow "shadowing" the type IGraphItem of your interface with the generic type IGraphItem in this method.
It would also work if you would explicitely tell the compiler that item As IGraphItem actually is a item As YourNamespace.IGraphItem.
I'm sure Jon or Eric could explain it better, but maybe it's helpful anyway ;)
This article might answer your question. If not, well, it's an excellent reading anyway.
http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx
If I create a class in VB called Test, I noticed I can instantiate it like:
Dim test As New Test
or
Dim test As New Test()
What is the difference?
There's no difference, they are the same, VB.NET will ignore the () since no parameters are being passed in.
There isn't one. Both versions will call the parameter-less constructor of the Test class. The second one just has parentheses.