隐藏公共职能

时间:2009-11-18 08:43:26

标签: vb.net reflection

这是一个相当普遍的问题,因为我只是想知道这有什么潜在的选择。

说,我有一个简单的课程:

    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

编辑:上面的类只是一个可以从Web服务返回的示例。我根本无法修改它,对不起,如果我没有说清楚的话。

是否有可能以某种方式创建一个克隆此类,以便它保留所有属性值,但隐藏了一个公共函数的事实?

我希望能够从Web服务(我们没有编写)中检索一些现有的类,并且能够将它们传递给应用程序,但不暴露这些函数。我不想沿着创建我自己的类的路线,专门定义每个属性并写入值(由于其中一些的大小),所以我想看看是否有任何动态我可以利用(也许有一种方法使用反射?)。

非常感谢任何想法。

谢谢, 标记

4 个答案:

答案 0 :(得分:1)

以下文章看起来概述了一些您可能会觉得有用的技巧。 http://coding-passion.blogspot.com/2008/12/adding-properties-to-object-dynamically.html

作者正在动态地向对象添加属性,这实际上就是您想要做的事情。您将遇到的唯一“问题”是,因为属性是动态的,您将需要使用反射来获取和设置它们(您的应用程序在运行之前不会知道属性 - 将无法使用在设计时直接引用它们)。以下是一些示例方法。

除此之外,我还没有意识到在从类继承时“隐藏”公共方法的方法。


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

答案 1 :(得分:0)

如果您只是想在库中公开该方法(并将其隐藏在您的应用程序中),我认为您希望在方法上使用Friend关键字而不是Public关键字。

答案 2 :(得分:0)

如果您无法更改Web服务(如果可以,您可以从DoSomething函数中删除[WebMethod]),也许您可​​以从客户端Web服务代理创建派生类并使用隐藏方法public new integer DoSomething() {}

(抱歉,我不知道VB.net的语法)

如果你想使它适用于任何对象,你可以设置某种外观,完全隐藏你的对象。 Facade有一个公共属性public Object obj { get; set; }和两个函数ReadMember和SetMember。这两个函数通过反射获取和设置obj的属性。

答案 3 :(得分:0)

此类是一个通用对象,它从传递给PropertyBag构造函数的对象中提取属性。然后,可以通过属性名称通用类型属性检索属性值。

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

示例用法是......

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