user4951
user4951

Reputation: 33090

Why I can't call interface function directly?

    For Each jt In json
        Dim jo1 = CType(jt, JObject)
        Dim id = jo1.Item("MarketID").ToString
        Dim basequote = dict(id)
        Dim jo2 As IDictionary(Of String, JToken) = jo1

        If Not (jo2.ContainsKey(jsonHelper.SpecialKeyForDictoToArray)) Then
            jo1.Add(jsonHelper.SpecialKeyForDictoToArray, dict(id))
            Dim b = 1
        End If
    Next

The idea is Jobject implements IDictionary(Of String, JToken) and hence I can do

        Dim jo2 As IDictionary(Of String, JToken) = jo1

However, I must be missing something here.

If Jobject implements some interface, should I be able to do

        If Not (jo1.ContainsKey(jsonHelper.SpecialKeyForDictoToArray)) 

right away?

Where did I went wrong?

Trying to do so yield this screenshot

enter image description here

I tried to check definition of JObject. It clearly states that it implements

IDictionary(Of String, JToken)

However, nowhere does I see it implements functions like containskey.

   '
' Summary:
'     Represents a JSON object.
<DefaultMember("Item")>
Public Class JObject
    Inherits JContainer
    Implements IDictionary(Of String, JToken), ICollection(Of KeyValuePair(Of String, JToken)), IEnumerable(Of KeyValuePair(Of String, JToken)), IEnumerable, INotifyPropertyChanged, ICustomTypeDescriptor, INotifyPropertyChanging
    '
    ' Summary:
    '     Initializes a new instance of the Newtonsoft.Json.Linq.JObject class.
    Public Sub New()
    '
    ' Summary:
    '     Initializes a new instance of the Newtonsoft.Json.Linq.JObject class from another
    '     Newtonsoft.Json.Linq.JObject object.
    '
    ' Parameters:
    '   other:
    '     A Newtonsoft.Json.Linq.JObject object to copy from.
    Public Sub New(other As JObject)
    '
    ' Summary:
    '     Initializes a new instance of the Newtonsoft.Json.Linq.JObject class with the
    '     specified content.
    '
    ' Parameters:
    '   content:
    '     The contents of the object.
    Public Sub New(ParamArray content() As Object)
    '
    ' Summary:
    '     Initializes a new instance of the Newtonsoft.Json.Linq.JObject class with the
    '     specified content.
    '
    ' Parameters:
    '   content:
    '     The contents of the object.
    Public Sub New(content As Object)

    '
    ' Summary:
    '     Gets or sets the Newtonsoft.Json.Linq.JToken with the specified property name.
    Default Public Property Item(propertyName As String) As JToken
    '
    ' Summary:
    '     Gets the Newtonsoft.Json.Linq.JToken with the specified key.
    Default Public Overrides Property Item(key As Object) As JToken
    '
    ' Summary:
    '     Gets the node type for this Newtonsoft.Json.Linq.JToken.
    Public Overrides ReadOnly Property Type As JTokenType
    '
    ' Summary:
    '     Gets the container's children tokens.
    Protected Overrides ReadOnly Property ChildrenTokens As IList(Of JToken)

    '
    ' Summary:
    '     Occurs when a property value is changing.
    Public Event PropertyChanging As PropertyChangingEventHandler
    '
    ' Summary:
    '     Occurs when a property value changes.
    Public Event PropertyChanged As PropertyChangedEventHandler

    '
    ' Summary:
    '     Adds the specified property name.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    '   value:
    '     The value.
    Public Sub Add(propertyName As String, value As JToken)
    '
    ' Summary:
    '     Writes this token to a Newtonsoft.Json.JsonWriter.
    '
    ' Parameters:
    '   writer:
    '     A Newtonsoft.Json.JsonWriter into which this method will write.
    '
    '   converters:
    '     A collection of Newtonsoft.Json.JsonConverter which will be used when writing
    '     the token.
    Public Overrides Sub WriteTo(writer As JsonWriter, ParamArray converters() As JsonConverter)
    '
    ' Summary:
    '     Raises the Newtonsoft.Json.Linq.JObject.PropertyChanging event with the provided
    '     arguments.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    Protected Overridable Sub OnPropertyChanging(propertyName As String)
    '
    ' Summary:
    '     Raises the Newtonsoft.Json.Linq.JObject.PropertyChanged event with the provided
    '     arguments.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    Protected Overridable Sub OnPropertyChanged(propertyName As String)

    '
    ' Summary:
    '     Load a Newtonsoft.Json.Linq.JObject from a string that contains JSON.
    '
    ' Parameters:
    '   json:
    '     A System.String that contains JSON.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject populated from the string that contains JSON.
    '
    ' Exceptions:
    '   T:Newtonsoft.Json.JsonReaderException:
    '     json is not valid JSON.
    Public Shared Function Parse(json As String) As JObject
    '
    ' Summary:
    '     Load a Newtonsoft.Json.Linq.JObject from a string that contains JSON.
    '
    ' Parameters:
    '   json:
    '     A System.String that contains JSON.
    '
    '   settings:
    '     The Newtonsoft.Json.Linq.JsonLoadSettings used to load the JSON. If this is null,
    '     default load settings will be used.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject populated from the string that contains JSON.
    '
    ' Exceptions:
    '   T:Newtonsoft.Json.JsonReaderException:
    '     json is not valid JSON.
    Public Shared Function Parse(json As String, settings As JsonLoadSettings) As JObject
    '
    ' Summary:
    '     Creates a Newtonsoft.Json.Linq.JObject from an object.
    '
    ' Parameters:
    '   o:
    '     The object that will be used to create Newtonsoft.Json.Linq.JObject.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject with the values of the specified object.
    Public Shared Function FromObject(o As Object) As JObject
    '
    ' Summary:
    '     Creates a Newtonsoft.Json.Linq.JObject from an object.
    '
    ' Parameters:
    '   o:
    '     The object that will be used to create Newtonsoft.Json.Linq.JObject.
    '
    '   jsonSerializer:
    '     The Newtonsoft.Json.JsonSerializer that will be used to read the object.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject with the values of the specified object.
    Public Shared Function FromObject(o As Object, jsonSerializer As JsonSerializer) As JObject
    '
    ' Summary:
    '     Loads a Newtonsoft.Json.Linq.JObject from a Newtonsoft.Json.JsonReader.
    '
    ' Parameters:
    '   reader:
    '     A Newtonsoft.Json.JsonReader that will be read for the content of the Newtonsoft.Json.Linq.JObject.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject that contains the JSON that was read from the
    '     specified Newtonsoft.Json.JsonReader.
    '
    ' Exceptions:
    '   T:Newtonsoft.Json.JsonReaderException:
    '     reader is not valid JSON.
    Public Shared Function Load(reader As JsonReader) As JObject
    '
    ' Summary:
    '     Asynchronously loads a Newtonsoft.Json.Linq.JObject from a Newtonsoft.Json.JsonReader.
    '
    ' Parameters:
    '   reader:
    '     A Newtonsoft.Json.JsonReader that will be read for the content of the Newtonsoft.Json.Linq.JObject.
    '
    '   cancellationToken:
    '     The token to monitor for cancellation requests. The default value is System.Threading.CancellationToken.None.
    '
    ' Returns:
    '     A System.Threading.Tasks.Task`1 that represents the asynchronous load. The System.Threading.Tasks.Task`1.Result
    '     property returns a Newtonsoft.Json.Linq.JObject that contains the JSON that was
    '     read from the specified Newtonsoft.Json.JsonReader.
    Public Shared Function LoadAsync(reader As JsonReader, Optional cancellationToken As CancellationToken = Nothing) As Task(Of JObject)
    '
    ' Summary:
    '     Asynchronously loads a Newtonsoft.Json.Linq.JObject from a Newtonsoft.Json.JsonReader.
    '
    ' Parameters:
    '   reader:
    '     A Newtonsoft.Json.JsonReader that will be read for the content of the Newtonsoft.Json.Linq.JObject.
    '
    '   settings:
    '     The Newtonsoft.Json.Linq.JsonLoadSettings used to load the JSON. If this is null,
    '     default load settings will be used.
    '
    '   cancellationToken:
    '     The token to monitor for cancellation requests. The default value is System.Threading.CancellationToken.None.
    '
    ' Returns:
    '     A System.Threading.Tasks.Task`1 that represents the asynchronous load. The System.Threading.Tasks.Task`1.Result
    '     property returns a Newtonsoft.Json.Linq.JObject that contains the JSON that was
    '     read from the specified Newtonsoft.Json.JsonReader.
    <AsyncStateMachineAttribute(GetType(<LoadAsync>d__2))>
    Public Shared Function LoadAsync(reader As JsonReader, settings As JsonLoadSettings, Optional cancellationToken As CancellationToken = Nothing) As Task(Of JObject)
    '
    ' Summary:
    '     Loads a Newtonsoft.Json.Linq.JObject from a Newtonsoft.Json.JsonReader.
    '
    ' Parameters:
    '   reader:
    '     A Newtonsoft.Json.JsonReader that will be read for the content of the Newtonsoft.Json.Linq.JObject.
    '
    '   settings:
    '     The Newtonsoft.Json.Linq.JsonLoadSettings used to load the JSON. If this is null,
    '     default load settings will be used.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JObject that contains the JSON that was read from the
    '     specified Newtonsoft.Json.JsonReader.
    '
    ' Exceptions:
    '   T:Newtonsoft.Json.JsonReaderException:
    '     reader is not valid JSON.
    Public Shared Function Load(reader As JsonReader, settings As JsonLoadSettings) As JObject
    '
    ' Summary:
    '     Gets an System.Collections.Generic.IEnumerable`1 of Newtonsoft.Json.Linq.JProperty
    '     of this object's properties.
    '
    ' Returns:
    '     An System.Collections.Generic.IEnumerable`1 of Newtonsoft.Json.Linq.JProperty
    '     of this object's properties.
    Public Function Properties() As IEnumerable(Of JProperty)
    '
    ' Summary:
    '     Gets a Newtonsoft.Json.Linq.JProperty the specified name.
    '
    ' Parameters:
    '   name:
    '     The property name.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JProperty with the specified name or null.
    Public Function [Property](name As String) As JProperty
    '
    ' Summary:
    '     Tries to get the Newtonsoft.Json.Linq.JToken with the specified property name.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    '   value:
    '     The value.
    '
    ' Returns:
    '     true if a value was successfully retrieved; otherwise, false.
    Public Function TryGetValue(propertyName As String, ByRef value As JToken) As Boolean
    '
    ' Summary:
    '     Removes the property with the specified name.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    ' Returns:
    '     true if item was successfully removed; otherwise, false.
    Public Function Remove(propertyName As String) As Boolean
    '
    ' Summary:
    '     Gets a Newtonsoft.Json.Linq.JEnumerable`1 of Newtonsoft.Json.Linq.JToken of this
    '     object's property values.
    '
    ' Returns:
    '     A Newtonsoft.Json.Linq.JEnumerable`1 of Newtonsoft.Json.Linq.JToken of this object's
    '     property values.
    Public Function PropertyValues() As JEnumerable(Of JToken)
    '
    ' Summary:
    '     Tries to get the Newtonsoft.Json.Linq.JToken with the specified property name.
    '     The exact property name will be searched for first and if no matching property
    '     is found then the System.StringComparison will be used to match a property.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    '   value:
    '     The value.
    '
    '   comparison:
    '     One of the enumeration values that specifies how the strings will be compared.
    '
    ' Returns:
    '     true if a value was successfully retrieved; otherwise, false.
    Public Function TryGetValue(propertyName As String, comparison As StringComparison, ByRef value As JToken) As Boolean
    '
    ' Summary:
    '     Gets the Newtonsoft.Json.Linq.JToken with the specified property name. The exact
    '     property name will be searched for first and if no matching property is found
    '     then the System.StringComparison will be used to match a property.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    '   comparison:
    '     One of the enumeration values that specifies how the strings will be compared.
    '
    ' Returns:
    '     The Newtonsoft.Json.Linq.JToken with the specified property name.
    Public Function GetValue(propertyName As String, comparison As StringComparison) As JToken
    '
    ' Summary:
    '     Gets the Newtonsoft.Json.Linq.JToken with the specified property name.
    '
    ' Parameters:
    '   propertyName:
    '     Name of the property.
    '
    ' Returns:
    '     The Newtonsoft.Json.Linq.JToken with the specified property name.
    Public Function GetValue(propertyName As String) As JToken
    '
    ' Summary:
    '     Returns an enumerator that can be used to iterate through the collection.
    '
    ' Returns:
    '     A System.Collections.Generic.IEnumerator`1 that can be used to iterate through
    '     the collection.
    <IteratorStateMachineAttribute(GetType(<GetEnumerator>d__61))>
    Public Function GetEnumerator() As IEnumerator(Of KeyValuePair(Of String, JToken))
    '
    ' Summary:
    '     Writes this token to a Newtonsoft.Json.JsonWriter asynchronously.
    '
    ' Parameters:
    '   writer:
    '     A Newtonsoft.Json.JsonWriter into which this method will write.
    '
    '   cancellationToken:
    '     The token to monitor for cancellation requests.
    '
    '   converters:
    '     A collection of Newtonsoft.Json.JsonConverter which will be used when writing
    '     the token.
    '
    ' Returns:
    '     A System.Threading.Tasks.Task that represents the asynchronous write operation.
    <AsyncStateMachineAttribute(GetType(<WriteToAsync>d__0))>
    Public Overrides Function WriteToAsync(writer As JsonWriter, cancellationToken As CancellationToken, ParamArray converters() As JsonConverter) As Task
    '
    ' Summary:
    '     Returns the System.Dynamic.DynamicMetaObject responsible for binding operations
    '     performed on this object.
    '
    ' Parameters:
    '   parameter:
    '     The expression tree representation of the runtime value.
    '
    ' Returns:
    '     The System.Dynamic.DynamicMetaObject to bind this object.
    Protected Overrides Function GetMetaObject(parameter As Expression) As DynamicMetaObject
End Class

You can look things up here

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm

There is no implementation of containsKey. Why?

Upvotes: 1

Views: 620

Answers (2)

djv
djv

Reputation: 15774

If the interface member is implemented but marked Private, it won't show up in the metadata or intellisense. This is explicit implementation. You can still access it through the interface. This is by design so it doesn't augment the public interface. Remember, Interfaces don't specify access levels though interface members are guaranteed to be available through the interface.

You'll need to cast the object as IDictionary(Of String, JToken) to access the interface member.

CType(jo1, IDictionary(Of String, JToken))

Either of these should work

If Not (CType(jo1, IDictionary(Of String, JToken)).ContainsKey(jsonHelper.SpecialKeyForDictoToArray)) Then
    jo1.Add(jsonHelper.SpecialKeyForDictoToArray, dict(id))
    Dim b = 1
End If

If Not (jo2.ContainsKey(jsonHelper.SpecialKeyForDictoToArray)) Then
    jo1.Add(jsonHelper.SpecialKeyForDictoToArray, dict(id))
    Dim b = 1
End If

In general, when you explicitly implement an interface, you must access the explicitly implemented member through the interface. One reason for this is multiple interface implementation. In the case

Class Foo
    Implements IBar, IBaz

    Public Sub Run() Implements IBar.Run
        Console.WriteLine("IBar")
    End Sub

    Private Sub IBaz_Run() Implements IBaz.Run
        Console.WriteLine("IBaz")
    End Sub

End Class

Interface IBar
    Sub Run()
End Interface

Interface IBaz
    Sub Run()
End Interface

Module Module1

    Sub Main()
        Dim myFoo As New Foo
        myFoo.Run() ' outputs IBar
        Dim myBaz As IBaz
        myBaz = DirectCast(myFoo, IBaz)
        myBaz.Run() ' outputs IBaz
        Console.ReadLine()
    End Sub

End Module

The class Foo implements two interfaces with the same member name but only one can be defined in the class Foo. By default, IBaz.Run() is marked private (explicit implementation). One must access IBaz.Run through the interface. IBaz_Run could be marked public but since the name is different, it won't show up on the public interface of Foo anyway.

This example describes a behavior, but it is a side effect of the language feature explicit implementation.

Upvotes: 1

user4951
user4951

Reputation: 33090

I am marking djv answer as the answer.

That being said I look around further and found this

https://msdn.microsoft.com/en-us/library/28e2e18x%28VS.100%29.aspx?f=255&MSPPError=-2147217396

You can use a private member to implement an interface member. When a private member implements a member of an interface, that member becomes available by way of the interface even though it is not available directly on object variables for the class.

So, interface can be private, which I think is a bit strange.

Upvotes: 0

Related Questions