C#中的typeof关键字

本文介绍了C#中使用typeof操作符获取类型信息的方法,并展示了如何通过GetType方法取得运行时表达式的类型。此外,还提供了两个示例代码,分别演示了获取特定类型的信息及通过数学运算结果确定其类型。

Used to obtain the System.Type object for a type. A typeof expression takes the following form:

System.Type type = typeof(int);

To obtain the run-time type of an expression, you can use the .NET Framework method GetType, like this:

int i = 0;
System.Type type = i.GetType();

The typeof operator can also be used on open generic types. Types with more then one type parameter must have the appropriate number of commas in the specification. The typeof operator cannot be overloaded.

// cs_operator_typeof.cs
using System;
using System.Reflection;

public class SampleClass
{
   public int sampleMember;
   public void SampleMethod() {}

   static void Main()
   {
      Type t = typeof(SampleClass);
      // Alternatively, you could use
      // SampleClass obj = new SampleClass();
      // Type t = obj.GetType();

      Console.WriteLine("Methods:");
      MethodInfo[] methodInfo = t.GetMethods();

      foreach (MethodInfo mInfo in methodInfo)
         Console.WriteLine(mInfo.ToString());

      Console.WriteLine("Members:");
      MemberInfo[] memberInfo = t.GetMembers();

      foreach (MemberInfo mInfo in memberInfo)
         Console.WriteLine(mInfo.ToString());
   }
}
Output
 
Methods:
Void SampleMethod()
System.Type GetType()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
Members:
Void SampleMethod()
System.Type GetType()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
Void .ctor()
Int32 sampleMember

This sample uses the GetType method to determine the type used to contain the result of a numeric calculation. This depends on the storage requirements of the resulting number.

// cs_operator_typeof2.cs
using System;
class GetTypeTest 
{
   static void Main() 
   {
      int radius = 3;
      Console.WriteLine("Area = {0}", radius * radius * Math.PI);
      Console.WriteLine("The type is {0}", 
                        (radius * radius * Math.PI).GetType()
      );
   }
}
Output
 
Area = 28.2743338823081
The type is System.Double
<think>嗯,用户现在想了解C#中dynamic关键字的用法、使用场景和示例。之前我们讨论了成员方法和静态方法的区别,现在需要结合用户提供的引用内容来回答。首先,用户给出的引用1提到dynamic可以简化反射调用,与动态语言互操作,引用2提到注意事项,比如运行时类型检查、异常处理,以及结合设计模式。引用3是关于性能监控的例子,引用4是MIDI的,可能不太相关。 用户的问题集中在dynamic关键字的使用场景,需要给出具体的例子和注意事项。根据引用1中的例子,动态调用Greet方法,省去了反射的繁琐代码。这个可以作为使用场景之一。另外,引用2提到与动态语言互操作,比如IronPython或COM组件交互,这也是dynamic的常见应用。此外,处理动态数据格式如JSON或XML,可能也是使用场景。 需要注意用户可能关心dynamic的性能影响,因为引用3提到了性能监控,虽然那个例子是Dynamics 365的监控,但可能可以引申到dynamic的运行时开销。引用2也强调不要滥用dynamic,应遵循必要性原则,所以在回答时需要提到何时适合使用dynamic,何时应避免。 另外,用户之前的讨论涉及线程安全和内存管理,虽然dynamic本身可能不直接相关,但在多线程环境下使用dynamic需要注意潜在的竞态条件,特别是当动态对象被多个线程访问时。不过可能这不是主要问题,但可以作为注意事项提及。 需要确保回答结构清晰,分使用场景、示例、注意事项。可能还要比较dynamic与var的区别,因为用户可能混淆这两者。比如var在编译时确定类型,而dynamic在运行时动态解析。 另外,用户提供的示例代码中有动态调用Greet方法,可以扩展这个例子,或者展示其他场景,比如处理JSON数据。同时,需要指出潜在的风险,比如缺少编译时类型检查,可能引发运行时异常,需要用try-catch处理。 最后,总结动态关键字的适用情况,强调在需要动态行为、与动态语言交互或简化反射代码时使用,但要注意性能和可维护性。确保引用用户提供的引用内容,比如引用1和引用2的内容,作为支持论据。</think>### C# `dynamic` 关键字深度解析 (结合核心场景与实战示例) --- #### **一、核心特性与本质** `dynamic` 是 C# 4.0 引入的动态类型标识符,其特性包括: - **运行时类型解析**:绕过编译时类型检查,在运行时动态绑定成员 - **DLR(动态语言运行时)支持**:与 IronPython、IronRuby 等动态语言无缝交互[^1] - **简化反射**:避免传统反射的繁琐代码,提升可读性 --- #### **二、关键使用场景与示例** **1. 动态反射调用** **传统反射**: ```csharp var type = typeof(Example); var obj = Activator.CreateInstance(type); var method = type.GetMethod("Greet"); method.Invoke(obj, new object[] { "Alice" }); ``` **使用 `dynamic` 简化**: ```csharp dynamic obj = Activator.CreateInstance(typeof(Example)); obj.Greet("Alice"); // 无需反射接口,直接调用 ``` **2. 动态语言互操作** 与 IronPython 交互示例: ```csharp using IronPython.Hosting; var engine = Python.CreateEngine(); dynamic scope = engine.CreateScope(); engine.Execute("def add(a, b): return a + b", scope); int result = scope.add(3, 5); // 动态调用 Python 函数 ``` **3. 处理动态数据结构** 解析 JSON 或 XML 等非结构化数据: ```csharp dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject( "{ \"name\": \"Alice\", \"age\": 30 }" ); Console.WriteLine(json.name); // 动态访问属性 ``` **4. COM 组件交互** 简化 Office 自动化操作: ```csharp dynamic excel = Microsoft.VisualBasic.Interaction.CreateObject("Excel.Application"); excel.Visible = true; dynamic workbook = excel.Workbooks.Add(); ``` --- #### **三、注意事项与最佳实践** **1. 性能权衡** - **运行时开销**:动态绑定比静态类型调用慢约 10-100 倍(视场景)[^2] - **高频调用优化**: ```csharp // 对高频动态调用可缓存委托 var greetMethod = (Action<string>)Delegate.CreateDelegate( typeof(Action<string>), obj, "Greet" ); greetMethod("Alice"); ``` **2. 类型安全防护** 强制使用 `try-catch` 处理潜在异常: ```csharp try { dynamic obj = GetUncertainObject(); obj.InvalidMethod(); } catch (RuntimeBinderException ex) { Console.WriteLine($"方法不存在: {ex.Message}"); } ``` **3. 设计模式结合** - **工厂模式**动态创建对象: ```csharp public dynamic CreateService(string serviceType) { return Activator.CreateInstance(Type.GetType(serviceType)); } ``` - **策略模式**实现动态行为切换: ```csharp public interface IStrategy { void Execute(); } dynamic strategy = GetStrategy(); strategy.Execute(); // 动态策略实现 ``` **4. 与静态类型混合规范** - **边界控制**:仅在必要模块使用 `dynamic`,核心逻辑保持静态类型 - **类型断言**:通过 `is` 或 `as` 进行安全转换 ```csharp if (dynamicObj is string text) { Console.WriteLine(text.ToUpper()); } ``` --- #### **四、与 `var` 的本质区别** | **特性** | `var` | `dynamic` | |----------------|--------------------------------|-------------------------------| | **类型确定** | 编译时推断(静态类型) | 运行时解析(动态类型) | | **智能提示** | 完整 IDE 支持 | 无成员智能提示 | | **性能** | 等效显式类型声明 | 额外运行时绑定开销 | --- #### **五、典型错误场景** ```csharp dynamic value = GetExternalData(); // 错误:未经验证直接访问可能不存在的属性 Console.WriteLine(value.Detail.Address); // 正确做法 if (HasProperty(value, "Detail") && HasProperty(value.Detail, "Address")) { Console.WriteLine(value.Detail.Address); } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值