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

2020-11-07 09:51:10 +08:00
 uubooks

有个 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#,平时就偶尔写写小程序,没有多少经验..所以遇到高级功能就蒙逼了.

2262 次点击
所在节点    程序员
25 条回复
uubooks
2020-11-07 10:05:59 +08:00
类名后面没有括号..我写错了..
allanpk716
2020-11-07 10:15:05 +08:00
bind 以及实现 covert
allanpk716
2020-11-07 10:15:46 +08:00
@allanpk716 忘记说了,WPF 的话 doge
fiveelementgid
2020-11-07 11:13:02 +08:00
自学+1,反射也没看懂,等一个带佬
还有,不建议你在这里使用自动属性{get;set;}
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
2020-11-07 11:29:49 +08:00
用 Attribute 标注属性 然后自己实现这个特性 反射的时候根据特性进行自动化
ian19znj
2020-11-07 11:32:23 +08:00
其实我没太看懂你的需求,不过要用反射取属性的话,这样写,typeofGetProperty(propertyName).GetValue(person)
ian19znj
2020-11-07 11:33:33 +08:00
写丢了。。Typeof(Person).GetProperty(propertyName).GetValue(person)
uubooks
2020-11-07 12:51:43 +08:00
谢谢楼上各位大佬的解答.
可能我问题描述得不太好.反射那些我知道.
我是想把我的类或接口的内容曝光给用户,让用户来决定相关的操作.
比如汽车类,有 color 属性,speed 属性,start,stop 方法.让用户可以选择颜色.启动汽车.
但这个 color 属性我在 WINFORM 界面针对不同国家用户可能要翻译成[中文,日文,英文].
而且这个汽车类不是我自己写的类,是别人写的类或接口,所以就蒙了.不知怎么弄.可能要用到特性吧.
@allanpk716
@di1012
@kiracyan
@ian19znj
beyondex
2020-11-07 13:04:09 +08:00
没太看明白,如果是多语言,感觉跟反射关系不大,多语言就用多语言的方案,也可以自己用字典实现。
如果需要动态反射操作,可以看下 Clay 这个库
xuanbg
2020-11-07 13:06:37 +08:00
@uubooks 你这个是本地化需求,和反射他就没关系呀。你在界面上显示 年龄:20 和显示 age:20,逻辑上是一回事。都是把 age 这个属性的值绑定到 age 这个 textbox 上面。至于这个 textbox 前面的文本显示成年龄还是 Age,要看用户选择的界面语言是中文还是英语。
beyondex
2020-11-07 13:08:50 +08:00
onepix
2020-11-07 13:24:59 +08:00
这还用得着反射,我没理解题意吗?!
chinvo
2020-11-07 13:25:59 +08:00
humanizer
uubooks
2020-11-07 13:45:10 +08:00
@onepix 要用到啊.如果只有 1 个 2 个属性,那我直接拖控件就可以了.二个 label 就好了.但是如果我有几十个上百个属性和方法呢.而且这个类对象不是固定的.我可能会操作汽车,动物类这样子.
uubooks
2020-11-07 13:48:41 +08:00
@beyondex 谢谢.资料我先收藏了.回去看一下.
chinni
2020-11-07 14:18:08 +08:00
就是根据类定义 生成 控件排列 直接用 attribute 然后挨个读取就行了
h82258652
2020-11-07 14:53:00 +08:00
这个最好还是说一下平台吧,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
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
2020-11-07 15:52:06 +08:00
@allanpk716 谢谢老哥.我回去 看一下.学得不够深入,搞些东西真蒙.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/722609

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX