V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
uubooks
V2EX  ›  程序员

请教大佬 C#反射相关问题

  •  
  •   uubooks · 2020-11-07 09:51:10 +08:00 · 2242 次点击
    这是一个创建于 1266 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个 C#相关问题咨询下各位大佬: 比如我有个这样的类 class person() {

      public int Age{get;set;}
      
      public string Name{get;set;}
      
      public void Run();
      
      public void SaySomeThing(string words);
      
      public otherObject Others{get; private set;}  //这个对象里面还有属性或方法
    }
    

    我现在想实现功能就是我在用户界面上对这个类的属性进行访问赋值,例如这样 我创建了一个小红的 person,界面上我选择了小红后,那么可选的属性 AGE 经过翻译后显示为[年龄],后面有个数字框 用户可以输入 50,选择 name 属性,经过翻译后显示为[姓名],后面显示一个文本框,让用户可以赋值.

    用户可以调用 RUN 方法.调用有参数的 SaySomeThing 方法.

    同时,如果是其它对象,下面还会显示该对象的属性这样子..

    我知道会用到反射.但具体不知该怎么做最好.

    请大佬指点迷津,因为自学 C#,平时就偶尔写写小程序,没有多少经验..所以遇到高级功能就蒙逼了.

    25 条回复    2020-11-18 10:55:58 +08:00
    uubooks
        1
    uubooks  
    OP
       2020-11-07 10:05:59 +08:00
    类名后面没有括号..我写错了..
    allanpk716
        2
    allanpk716  
       2020-11-07 10:15:05 +08:00 via iPhone
    bind 以及实现 covert
    allanpk716
        3
    allanpk716  
       2020-11-07 10:15:46 +08:00 via iPhone
    @allanpk716 忘记说了,WPF 的话 doge
    fiveelementgid
        4
    fiveelementgid  
       2020-11-07 11:13:02 +08:00 via Android
    自学+1,反射也没看懂,等一个带佬
    还有,不建议你在这里使用自动属性{get;set;}
    di1012
        5
    di1012  
       2020-11-07 11:13:49 +08:00
    //基类
    class BaseClass
    {
    public int BaseField = 0;
    }
    //派生类
    class DerivedClass : BaseClass
    {
    public int DerivedField = 0;
    }
    class Program
    {
    static void Main(string[] args)
    {
    var bc = new BaseClass();
    var dc = new DerivedClass();
    BaseClass[] bca = new BaseClass[] { bc, dc };
    foreach(var v in bca)
    {
    //获取类型
    Type t = v.GetType();
    Console.WriteLine("Object Type: {0}", t.Name);
    //获取类中的字段
    FieldInfo[] fi = t.GetFields();
    foreach (var f in fi)
    Console.WriteLine(" Field:{0}", f.Name);
    Console.WriteLine();
    }
    Console.WriteLine("End!");
    Console.ReadKey();
    }
    }

    网上找的,同理类似,自己研究下就会了
    kiracyan
        6
    kiracyan  
       2020-11-07 11:29:49 +08:00
    用 Attribute 标注属性 然后自己实现这个特性 反射的时候根据特性进行自动化
    ian19znj
        7
    ian19znj  
       2020-11-07 11:32:23 +08:00 via iPhone
    其实我没太看懂你的需求,不过要用反射取属性的话,这样写,typeofGetProperty(propertyName).GetValue(person)
    ian19znj
        8
    ian19znj  
       2020-11-07 11:33:33 +08:00 via iPhone
    写丢了。。Typeof(Person).GetProperty(propertyName).GetValue(person)
    uubooks
        9
    uubooks  
    OP
       2020-11-07 12:51:43 +08:00
    谢谢楼上各位大佬的解答.
    可能我问题描述得不太好.反射那些我知道.
    我是想把我的类或接口的内容曝光给用户,让用户来决定相关的操作.
    比如汽车类,有 color 属性,speed 属性,start,stop 方法.让用户可以选择颜色.启动汽车.
    但这个 color 属性我在 WINFORM 界面针对不同国家用户可能要翻译成[中文,日文,英文].
    而且这个汽车类不是我自己写的类,是别人写的类或接口,所以就蒙了.不知怎么弄.可能要用到特性吧.
    @allanpk716
    @di1012
    @kiracyan
    @ian19znj
    beyondex
        10
    beyondex  
       2020-11-07 13:04:09 +08:00 via Android
    没太看明白,如果是多语言,感觉跟反射关系不大,多语言就用多语言的方案,也可以自己用字典实现。
    如果需要动态反射操作,可以看下 Clay 这个库
    xuanbg
        11
    xuanbg  
       2020-11-07 13:06:37 +08:00
    @uubooks 你这个是本地化需求,和反射他就没关系呀。你在界面上显示 年龄:20 和显示 age:20,逻辑上是一回事。都是把 age 这个属性的值绑定到 age 这个 textbox 上面。至于这个 textbox 前面的文本显示成年龄还是 Age,要看用户选择的界面语言是中文还是英语。
    beyondex
        12
    beyondex  
       2020-11-07 13:08:50 +08:00 via Android
    onepix
        13
    onepix  
       2020-11-07 13:24:59 +08:00 via iPhone
    这还用得着反射,我没理解题意吗?!
    chinvo
        14
    chinvo  
       2020-11-07 13:25:59 +08:00 via iPhone
    humanizer
    uubooks
        15
    uubooks  
    OP
       2020-11-07 13:45:10 +08:00
    @onepix 要用到啊.如果只有 1 个 2 个属性,那我直接拖控件就可以了.二个 label 就好了.但是如果我有几十个上百个属性和方法呢.而且这个类对象不是固定的.我可能会操作汽车,动物类这样子.
    uubooks
        16
    uubooks  
    OP
       2020-11-07 13:48:41 +08:00
    @beyondex 谢谢.资料我先收藏了.回去看一下.
    chinni
        17
    chinni  
       2020-11-07 14:18:08 +08:00
    就是根据类定义 生成 控件排列 直接用 attribute 然后挨个读取就行了
    h82258652
        18
    h82258652  
       2020-11-07 14:53:00 +08:00   ❤️ 1
    这个最好还是说一下平台吧,asp.net core 里我倒是知道
    ```C#
    public class Person
    {
    [Display(Name = "密码")]
    [DataType(DataType.Password)]
    public string Password{get;set;}
    }
    ```
    然后 Razor 里这样
    ```
    @Html.Editor(model=>mode.Password)
    ```
    就会生成<input type="password">类似的代码

    Winform 和 WPF 里据我所知是没有的。另外个人观点,与其用反射,不如用代码生成,按你自己的规则把这个类对应的控件代码生成出来,反正运行期间类又不可能会改变的。
    allanpk716
        19
    allanpk716  
       2020-11-07 15:17:14 +08:00
    @uubooks 按你的需求 WPF 很容易实现。控件 bind 数据源的属性( Car.Color ),然后通过 bind 的 convert 转换到你想要的语言。用户看到的显示值其实是 covert 的结果,但是选择的其实还是属性的值。所以未必需要反射来实现。

    花点时间入门下 WPF 吧,你会发现如果是面向 Windows 桌面开发,WPF 太爽了。看懂 WPF bind 就差不多可以跟 Winform 对着干了。

    抛个砖,抄段代码,别纠结于细节(逃

    *.cs

    /// <summary>
    /// 将性别转换为字符串
    /// </summary>
    public class ConverterSexsAnimal2String : IValueConverter
    {

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    if (value.ToString() == string.Empty)
    return SexsAnimalConverter.ToString(Sexs.Unknow);

    Sexs type = (Sexs)System.Enum.Parse(typeof(Sexs), value.ToString());

    return SexsAnimalConverter.ToString(type);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    return null;
    }
    }


    string SexsAnimalConverter.ToString(Sexs sex)
    {
    string str;

    switch (sex)
    {
    case Sexs.Male:
    {
    // 这里就是多国语言的每个字段对应的 key,具体去看怎么实现多国语言的。
    str = ResourceHelper.FindResoure("str_Male");
    break;
    }
    case Sexs.Female:
    {
    str = ResourceHelper.FindResoure("str_Female");
    break;
    }
    case Sexs.Unknow:
    {
    str = ResourceHelper.FindResoure("str_SexUnkonw");
    break;
    }
    default:
    str = string.Empty;
    break;

    }
    return str;

    }

    界面 bind
    .xaml
    这里是单向 bind,你得看 Mode 可选项。
    <DataGridTextColumn Binding="{Binding Sex,Converter={StaticResource ConverterSexsAnimal2String}, Mode=OneWay}" ....... />
    uubooks
        20
    uubooks  
    OP
       2020-11-07 15:52:06 +08:00
    @allanpk716 谢谢老哥.我回去 看一下.学得不够深入,搞些东西真蒙.
    wangbudong
        21
    wangbudong  
       2020-11-07 15:54:14 +08:00
    这关反射什么事
    BigBunny
        22
    BigBunny  
       2020-11-07 18:03:44 +08:00 via iPhone
    这个最好使用自定义特性配合使用
    smilenceX
        23
    smilenceX  
       2020-11-07 22:29:37 +08:00
    如果你只是需要绑定,前面已经有人说过了
    如果你是需要实现一个像 visual studio 的属性编辑器那样的功能,可以在 github 搜 property grid,有相应的实现。
    ian19znj
        24
    ian19znj  
       2020-11-07 23:41:57 +08:00 via iPhone
    我明白楼主的意思了,楼上正解,PropertyGrid 应该就是。推荐 Xceed 家的 PropertyGrid,这里附个链接,楼主你看看是不是你想要的。
    https://github.com/xceedsoftware/wpftoolkit/wiki/PropertyGrid
    forgottencoast
        25
    forgottencoast  
       2020-11-18 10:55:58 +08:00
    这使用了哪一个框架来做界面的? WinForm 还是 WPF ?还是别的?
    如果还没开始,用 WinForm 最简单,什么都不用学,直接获取值给界面赋值就可以了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2482 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 01:11 · PVG 09:11 · LAX 18:11 · JFK 21:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.