none
有关类型转换的问题 RRS feed

  • 问题

  • 查询了MSDN中关于各类型转换函数,发现必须提供一个具体的类型参数。比如CType函数和DirectCast函数,都必须在第二个参数中显式地给出具体的类型。比如:

    CType(TextBox1.Text, Int32)

    有没有一种函数或者方法可以在“目标类型”的地方以一个变量的形式传递参数?比如:

    1 somePropertyInfo = anInstance.GetType.GetProperty(InputBox())
    2 Dim aType As Type = somePropertyInfo.PropertyType
    3 A_Function(TextBox1.Text, aType)

    我在InputBox中输入一个属性(Property)名称,第1句根据这个名称获得一个PropertyInfo对象,第2句获得这个属性的类型(字符串或者其他类型),第3句自动将某文本框的文字转换为这个类型。

    事实上我在学习反射的时候遇到了这个问题。我自定义一个类Human,有两个公共属性:Name As String和Age As Integer。在窗体上放一个TreeView,窗体加载的时候将一个自定义类的所有公共属性的名称放在这个TreeView中。然后我单击TreeView中的某个TreeNode,某个文本框显示相应属性的值。虽然有两种类型(String和Integer),但可以统一用ToString方法显示到文本框上。而反过来,我在文本框中更改了这个值,希望写入到相应的属性中,这时候就遇到这个问题了。虽然我可以写一段根据不同类型而选择相应的CXXX转换函数,但我希望有个单一的转换函数,将文本框中的字符串,转换到前面所选的属性的类型。比如我前面单击TreeNode选择的是Age属性,这是Integer类型的值,所以必须将字符串先转换为整型,继而再转换为Object对象,最后传递给Type.InvokeMember函数的params数组参数中才行。因为存在两种类型的属性,所以必须针对每一种类型写一个转换语句,显得比较繁琐。有没有统一的方式将一个类型转换到另一个以变量形式存储的目标类型的方法?

    下面是我学习过程中写的程序:

    Imports System.Reflection
    
    Public Class Human
    
      Private _name As String = "Tom"
      Private _age As Integer = 24
    
      Public Property Name() As String
        Get
          Return _name
        End Get
        Set(ByVal value As String)
          _name = value
        End Set
      End Property
    
      Public Property Age() As Integer
        Get
          Return _age
        End Get
        Set(ByVal value As Integer)
          _age = value
        End Set
      End Property
    
    End Class
    
    Public Class Form1
    
      Dim Tom As New Human
      Dim propNode As TreeNode  '存放所选中的节点
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim humanType As Type = Tom.GetType
        Dim properties As Reflection.PropertyInfo() = humanType.GetProperties
    
        For Each prop As Reflection.PropertyInfo In properties
          TreeView1.Nodes.Add(prop.Name)
        Next
      End Sub
    
      Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
        Dim humanType As Type = Tom.GetType
        TextBox1.Text = humanType.GetProperty(e.Node.Text).GetValue(Tom, Nothing).ToString
        propNode = e.Node
      End Sub
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If propNode IsNot Nothing Then
          '设置绑定方式为:公共、实例和设置属性值
          Dim bf As BindingFlags = BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.SetProperty
          '根据节点内容获取一个属性
          Dim propInfo As PropertyInfo = Tom.GetType.GetProperty(propNode.Text)
          '获得该属性的数据类型
          Dim propType As Type = propInfo.PropertyType
    
          '下面必须对每一个属性类型写 InvokeMember 方法:
          If propInfo.PropertyType Is Type.GetType("System.String") Then
            Tom.GetType.InvokeMember(propNode.Text, bf, Nothing, Tom, New Object() {TextBox1.Text})
          ElseIf propInfo.PropertyType Is Type.GetType("System.Int32") Then
            Tom.GetType.InvokeMember(propNode.Text, bf, Nothing, Tom, New Object() {CInt(TextBox1.Text)})
          End If
    
          '是否存在某个统一的类型转换方式,使得调用 InvokeMember 如下形式:
          'Tom.GetType.InvokeMember(propNode.Text, bf, Nothing, Tom, New Object(){ A_Function(TextBox1.Text, propType)}
    
          TreeView1.Refresh()
        End If
      End Sub
    End Class
    
    
    
    2010年11月25日 5:02

答案

  • 参考一下哦,希望有帮助:

     using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication1
    {
        class Program
        {
            private class Student
            {
                public int ID { get; set; }
                public string Name { get; set; }
            }
            static void GeneralConvertProperty<T>(string propertyName, object propertyValue,T obj)
            {
                obj.GetType().GetProperty(propertyName).SetValue(obj,propertyValue,null);
            }
            static void Main(string[] args)
            {
                Student s = new Student();
                GeneralConvertProperty<Student>("ID", 1, s);  因为任何对象都可以隐式转化成object的,所以String通过此方法先转换成object利用反射赋值。
                Console.WriteLine(s.ID);
            }
        }
    }

    2010年11月26日 2:40
    版主