views:

96

answers:

4

Hi,

This is a fairly generic question in that I'm just wondering what potential options there are for this.

Say, I have a simple class:

    Public Class Example

    Private _One As String

    Public Property One() As String
        Get
            Return _One
        End Get
        Set(ByVal value As String)
            _One = value
        End Set
    End Property

    Public Function DoSomething() As Integer

    End Function
End Class

EDIT: The above class is just an example of what could be returned from a web service. I won't have access to modify it at all, sorry if I didn't make that clear.

Is it possible to somehow make a clone this class, so that it retains all of the properties values, but hides the fact that there is a Public function?

I'd like to be able to take some existing classes we retrieve from a web service (which we didn't write) and be able to pass them on for use in an application, but without exposing the functions. I don't want to go down the route of creating my own classes that specifically define each property and write the values in (due to the sheer size of some of them), so I'm looking to see if there is anything dynamic I can utilise (maybe there is a way using reflection?).

Any ideas would be greatly appreciated.

Thanks, Mark

A: 

If you just want to expose the method in your library (and hide it from your application), I think you want the Friend keyword instead of the Public keyword on your method.

adrianos
Hi, I can't change the access levels of the functions as they are in a compiled web service that we didn't write. So, I want to be able to take a clone of the class and somehow hide the functions.
ca8msm
I completely missed the point there, sorry. I'll have a think but I'm not hopeful.
adrianos
A: 

If you're not able to alter the webservice (if you could, you can remove [WebMethod] from the DoSomething function), maybe you could create a derived class from the clientside webservice proxy and hide the method by using public new integer DoSomething() {}

(Sorry I don't know the VB.net syntax)

If you want to make it work for any object, you could device some kind of facade, hiding your object completely. The facade has a public property public Object obj { get; set; } and two functions ReadMember and SetMember. Those two functions get and set the attributes on the obj by means of reflection.

Michel van Engelen
Hi, thanks for your answer but that doesn't make the solution dynamic. I'm looking for something that can take _any_ class (the one I posted is just an example to demonstrate) and hide the public functions.
ca8msm
+1  A: 

Looks like the following article outlines some techniques that you may find useful. http://coding-passion.blogspot.com/2008/12/adding-properties-to-object-dynamically.html

The author is dynamically adding properties to an object which is essentially what you're going to want to do. The only "problem" that you will run in to would be, because the properties are dynamic, you will need to use reflection to get and set them (your app will not be aware of the properties until it runs - won't be able to directly reference them at design time). Below are some sample methods to do that.

Beyond that, I'm not aware of a way to "hide" public methods when inheriting from a class.


Public Function SetProperty(ByVal obj As Object, ByVal PropertyName As String, ByVal val As Object) As Boolean
    Dim property_value As Object
    Dim properties_info As System.Reflection.PropertyInfo() = obj.GetType.GetProperties
    Dim property_info As System.Reflection.PropertyInfo

    For Each prop As System.Reflection.PropertyInfo In properties_info
        If prop.Name = PropertyName Then property_info = prop
    Next

    If property_info IsNot Nothing Then
        Try
            property_info.SetValue(obj, val, Nothing)
            Return True
        Catch ex As Exception
            Return False
        End Try
    Else
        Return False
    End If
End Function

Public Function GetProperty(ByVal obj As Object, ByVal PropertyName As String) As Object
    Dim property_value As Object
    Dim properties_info As System.Reflection.PropertyInfo() = obj.GetType.GetProperties
    Dim property_info As System.Reflection.PropertyInfo

    For Each prop As System.Reflection.PropertyInfo In properties_info
        If prop.Name = PropertyName Then property_info = prop
    Next

    If property_info IsNot Nothing Then
        Try
            property_value = property_info.GetValue(obj, Nothing)
            Return property_value
        Catch ex As Exception
            Return Nothing
        End Try
    Else
        Return Nothing
    End If
End Function

http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.setvalue.aspx http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.getvalue.aspx

brad.huffman
Thanks, this looks like it could be useful. Rather than "hiding" functions, if I can just copy properties over to a new object that would achieve the same goal. I'll look into this and get back to you, thanks.
ca8msm
A: 

This class is a generic object that extracts the Properties from an object that is passed in to the PropertyBag's constructor. The property values can then be retrieved through the generic Type properties by property name.

Imports System
Imports System.Collections.Generic

Public Class PropertyBag

    Private _Ints As Dictionary(Of String, Integer)
    Private _Strings As Dictionary(Of String, String)

    Sub New(ByVal obj As Object)

        Dim name As String
        Dim value As Object
        Dim prop As Reflection.PropertyInfo

        _Ints = New Dictionary(Of String, Integer)
        _Strings = New Dictionary(Of String, String)

        For Each prop In obj.GetType.GetProperties
            name = prop.Name.ToUpper
            value = prop.GetValue(obj, Nothing)

            Select Case prop.PropertyType.Name
                Case "Int32"
                    _Ints.Add(name, CType(value, Integer))
                Case "String"
                    _Strings.Add(name, value.ToString)
            End Select
        Next

    End Sub

    Public Function [Integer](ByVal sKey As String) As Integer
        Return _Ints(sKey.ToUpper)
    End Function
    Public Function [String](ByVal sKey As String) As String
        Return _Strings(sKey.ToUpper)
    End Function

End Class

A sample usage would be...

Public Class Example

    Private _one As String
    Private _two As Integer

    Public Property One() As String
        Get
            Return _one
        End Get
        Set(ByVal value As String)
            _one = value
        End Set
    End Property
    Public Property Two() As Integer
        Get
            Return _two
        End Get
        Set(ByVal value As Integer)
            _two = value
        End Set
    End Property

    Public Function DoSomething() As Integer
        Return 666
    End Function

End Class

Sub Main()

    Dim s As String
    Dim i As Integer
    Dim ex As New Example

    ex.One = "ONE"
    ex.Two = 2

    Dim o As New PropertyBag(ex)

    s = o.String("One")
    i = o.Integer("Two")

    Stop

End Sub
Bill