win10 uwp 反射

# win10 uwp 反射

本文在[h神](http://www.cnblogs.com/h82258652)的指导下完成。

反射是强大的好用的,我们可以添加新功能不修改之前的代码,通过使用反射得到。

本文下面和大家说如何做一个和WPF一样的反射功能,如何才能获的 UWP 程序集所有类。

 


先来说下反射。

.Net 最小单位是装配件,什么是装配件?其实就是 dll 或 exe 。.Net 程序包括 程序集 ,模块 , 类型 这几个。反射可以在程序运行得到这几个组成部分的相关信息。

反射可以获得`Assembly`,他可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。可以获得`Type`,他可以获得对象的类型信息,包括属性方法,可以调用属性方法。可以获得`MethodInfo`,他可以得到类方法的参数、返回值,可以调用方法。和`MethodInfo`差不多的,还有很多,都在`System.Reflection`可以看到。

反射是做什么?反射其实应用在对于类型差不多,但是需要对修改时不需要修改多处的代码使用。

- 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型

- 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射

- 反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。

在我写的[MVVM](./win10-uwp-MVVM%E5%85%A5%E9%97%A8/),就使用反射获得ViewModel,这样添加ViewModel 不需要修改写的代码。

反射可以添加类型不需要修改代码,这是很好的,但是反射性能比较差,在需要使用的时候才使用反射,不要每次都使用。

编译可以知道类型写错,反射不知道,可以得到错误的,一般使用反射需要小心,如果使用一些工具修改,那么反射得到的容易错误,好在C# 6有 `name of` 可以获得一个属性或方法的名称,这样使用他进行反射,得到的值才不容易出错。

反射可以获得安全类型的类,如internal或其他不是public的访问的类或类的字段,都可以获得。

 

## uwp 程序集所有类

我们可以使用下面代码获得程序集所有的类

```csharp
Application.Current.GetType().GetTypeInfo().Assembly

```

```csharp
foreach (var temp in applacationAssembly.DefinedTypes)
{

}

```

那么我们如何获得属于ViewModel的类,如果我们没有继承base,那我们有简单方法。

 

```csharp
public class ViewModelAssembly:Attribute
{

}
[ViewModelAssembly]
public class DstidModel : ViewModelBase

```
我们可以通过Attribute,查看是否有,如果有,就是ViewModel

 

```csharp
foreach (var temp in applacationAssembly.DefinedTypes)
{
if (temp.CustomAttributes.Any(t => t.AttributeType == typeof(ViewModelAssembly)))
{

}
}

```

当然我们还修改下,因为我们不需要写那么多

 

```csharp
var applacationAssembly = Application.Current.GetType().GetTypeInfo().Assembly;
foreach (var temp in applacationAssembly.DefinedTypes
.Where(temp=>temp.CustomAttributes.Any(t => t.AttributeType == typeof(ViewModelAssembly))))
{

}

```
那么我们可以使用type得到ViewModel,参见http://lindexi.oschina.io/lindexi/post/win10-uwp-%E4%BB%8EType%E4%BD%BF%E7%94%A8%E6%9E%84%E9%80%A0/

## 判断类型继承

经常需要判断 UWP 的类是否继承接口,如果需要判断继承接口,可以使用下面代码

1. 判断类型是否接口


```csharp
type.GetTypeInfo().IsInterface
```
就可以判断是否接口

接口的判断继承和类不同,接口判断使用下面的方式。这里 type 是一个类型,而 a 就是一个实例。


```csharp
type.IsAssignableFrom(a.GetType().GetTypeInfo());

```
上面的代码可以写为


```csharp
type.IsInstanceOfType(a)
```

如果不是接口,可以使用下面代码


```csharp
a.GetType().GetTypeInfo().IsSubclassOf(type);
```

## 获得特性

例如已经拿到 `TypeInfo` ,他的扩展方法可以拿到特定的特性,一般获得特性就是这个方法,请看代码。

```csharp
var attribute = type.GetCustomAttribute<LindexiAttribute>();
```

上面代码用于获得在对应类型的`LindexiAttribute`特性,于是就可以获得特性的实例,直接使用特性的属性就可以。

## [设置 .NET Native 运行时指令以支持反射(尤其适用于 UWP) - walterlv](https://walterlv.github.io/uwp/2017/09/21/reflection-using-dotnet-native-runtime-directive.html )

解决 Relase 上无法使用反射的问题

## WPF 反射获得所有类


```csharp
Assembly assembly = Assembly.GetExecutingAssembly();
foreach (var temp in assembly.GetTypes())
{


}
```

 

### 获得类型

1. typeof


```csharp
Type type = typeof(类型);
```


2. System.Object.GetType

所有的类存在的方法,通过一个实例,可以获得实例的

 

```csharp
类型 t = new 类型();

Type type=t.GetType();
```


1. System.Type.GetType


```csharp
Type type=Type.GetType("cvte.类型",false,true);
```

注意参数0是类名,参数1表示若找不到对应类时是否抛出异常,参数1表示类名是否区分大小写

### 创建对象

创建对象的方法很多

```csharp
Assembly assembly = Assembly.Load("Assembly");

Type type = assembly.GetType("Example");

object obj =Activator.CreateInstance(type);
```
可以传入参数,参数可以传入多个

```csharp
object obj = Activator.CreateInstance(type,参数);
```

另一个方法

```csharp
object obj = type.Assembly.CreateInstance(type.FullName);
```

### 获得方法

获得类型方法


```csharp
MethodInfo[] listMethodInfo = type.GetMethods();
```

使用方法


```csharp
object obj =Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("方法");
methodInfo.Invoke(obj,null); //参数1类型为object[],代表方法的对应参数,输入值为null代表没有参数
```

### 获得属性


```csharp
object obj =Activator.CreateInstance(type);

PropertyInfo propertyInfo = obj.GetProperty("Name"); //获取Name属性对象

var name = propertyInfo.GetValue(obj,null); //获取Name属性的值

propertyInfo.SetValue(obj,"cvte",null); //设置Name属性
```


### 获得Attribute


```csharp
object[] typeAttributes = type.GetCustomAttributes(false);
```

 

### 判断一个类是另一个的子类


```csharp
class A
{

}

class A1:A
{

}

A1 a=new A1();
a.GetType().IsSubclassOf(typeof(A)) 如果返回true,那么a就是继承 A
```

注意,虽然可以使用`BaseType`判断,但是如果继承多了,那么判断是否存在A,是不对的。

虽然说了很多,但很多都是大神讲的,于是

推荐大神讲的反射:http://www.cnblogs.com/wangshenhe/p/3256657.html

https://www.codeproject.com/Articles/55710/Reflection-in-NET

### 反射判断类继承接口

判断一个类继承接口的方法不可以使用 IsSubclassOf 判断

假如有下面的代码


```csharp
interface IA
{

}

class A : IA
{

}
```

这个代码会返回false `a.GetType().IsSubclassOf(typeof(IA));`

那么在C#如何判断一个类继承了接口,和一个类实现了接口?

使用方法是用 接口的[IsAssignableFrom](https://docs.microsoft.com/zh-cn/dotnet/api/system.type.isassignablefrom?view=netframework-4.7.1)进行判断


```csharp
A a = new A();

Console.WriteLine(typeof(IA).IsAssignableFrom(a.GetType()));
```

这时返回的是 true。

实际上 `IsAssignableFrom` 不仅可以用在接口,还可以用在类型,无论是什么的判断,这个方法的意思是,传入的类型是否继承于这个类型。所以只要判断继承,就可以使用这个方法。

请看下面例子,存在类型`Room`、`Kitchen`、`Bedroom`、`Guestroom`、`MasterBedroom` 继承关系如下

```csharp
class Room
{
}

class Kitchen : Room
{
}

class Bedroom : Room
{
}

class Guestroom : Bedroom
{
}

class MasterBedroom : Bedroom
{
}


```

这时使用下面的代码判断继承

```csharp
Room room1 = new Room();
Kitchen kitchen1 = new Kitchen();
Bedroom bedroom1 = new Bedroom();
Guestroom guestroom1 = new Guestroom();
MasterBedroom masterbedroom1 = new MasterBedroom();

Type room1Type = room1.GetType();
Type kitchen1Type = kitchen1.GetType();
Type bedroom1Type = bedroom1.GetType();
Type guestroom1Type = guestroom1.GetType();
Type masterbedroom1Type = masterbedroom1.GetType();

Console.WriteLine("room assignable from kitchen: {0}", room1Type.IsAssignableFrom(kitchen1Type));
Console.WriteLine("bedroom assignable from guestroom: {0}", bedroom1Type.IsAssignableFrom(guestroom1Type));
Console.WriteLine("kitchen assignable from masterbedroom: {0}", kitchen1Type.IsAssignableFrom(masterbedroom1Type));

```

可以看到有下面的输出

```csharp
// room assignable from kitchen: True
// bedroom assignable from guestroom: True
// kitchen assignable from masterbedroom: False
```

只要存在继承,那么就是返回true,如果不存在,那么返回false

如果自己和自己比较?如`Console.WriteLine("room assignable from room: {0}", typeof(Room).IsAssignableFrom(typeof(Room)));` 会返回true

如果类型 A 继承 B ,无论B是接口还是类,`B.IsAssignableFrom(A)` 返回 true 。如果 A 和 B 类型相同,那么同样返回 true

但是 IsAssignableFrom 使用的是类型,如果有一个类实现,可以尝试下面代码


```csharp
typeof(IA).IsInstanceOfType(a)
```

这个方法也可以获得类是否继承接口。

参见: [在C#中判断某个类是否实现了某个接口 ](https://leonax.net/p/3697/determine-if-a-class-implements-a-certain-interface/)

![](http://7xqpl8.com1.z0.glb.clouddn.com/34fdad35-5dfe-a75b-2b4b-8c5e313038e2%2F201792392836.jpg)

<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="知识共享许可协议" style="border-width:0" src="https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png" /></a><br />本作品采用<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议</a>进行许可。欢迎转载、使用、重新发布,但务必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我[联系](mailto:lindexi_gd@163.com)。

 

 

 

 

转载于:https://www.cnblogs.com/lindexi/p/6949661.html

CSDN海神之光上传的代码均可运行,亲测可用,直接替换数据即可,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b或2023b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪(CEEMDAN)、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 1. EMD(经验模态分解,Empirical Mode Decomposition) 2. TVF-EMD(时变滤波的经验模态分解,Time-Varying Filtered Empirical Mode Decomposition) 3. EEMD(集成经验模态分解,Ensemble Empirical Mode Decomposition) 4. VMD(变分模态分解,Variational Mode Decomposition) 5. CEEMDAN(完全自适应噪声集合经验模态分解,Complementary Ensemble Empirical Mode Decomposition with Adaptive Noise) 6. LMD(局部均值分解,Local Mean Decomposition) 7. RLMD(鲁棒局部均值分解, Robust Local Mean Decomposition) 8. ITD(固有时间尺度分解,Intrinsic Time Decomposition) 9. SVMD(逐次变分模态分解,Sequential Variational Mode Decomposition) 10. ICEEMDAN(改进的完全自适应噪声集合经验模态分解,Improved Complementary Ensemble Empirical Mode Decomposition with Adaptive Noise) 11. FMD(特征模式分解,Feature Mode Decomposition) 12. REMD(鲁棒经验模态分解,Robust Empirical Mode Decomposition) 13. SGMD(辛几何模态分解,Spectral-Grouping-based Mode Decomposition) 14. RLMD(鲁棒局部均值分解,Robust Intrinsic Time Decomposition) 15. ESMD(极点对称模态分解, extreme-point symmetric mode decomposition) 16. CEEMD(互补集合经验模态分解,Complementary Ensemble Empirical Mode Decomposition) 17. SSA(奇异谱分析,Singular Spectrum Analysis) 18. SWD(群分解,Swarm Decomposition) 19. RPSEMD(再生相移正弦辅助经验模态分解,Regenerated Phase-shifted Sinusoids assisted Empirical Mode Decomposition) 20. EWT(经验小波变换,Empirical Wavelet Transform) 21. DWT(离散小波变换,Discraete wavelet transform) 22. TDD(时域分解,Time Domain Decomposition) 23. MODWT(最大重叠离散小波变换,Maximal Overlap Discrete Wavelet Transform) 24. MEMD(多元经验模态分解,Multivariate Empirical Mode Decomposition) 25. MVMD(多元变分模态分解,Multivariate Variational Mode Decomposition)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值