【发布时间】:2011-06-10 10:51:28
【问题描述】:
我希望有两个答案之一,要么是不可能的,要么是极其简单的,我忽略了明显的 Google 查询。
根本问题是我有一个通过EventHandler 传入的通用对象,该对象将对象装箱并混淆了真实类型;只有在运行时我才知道对象是什么。
诚然,dynamic 关键字可以解决这个问题,但如果可以避免的话,我希望不要丢失 IntelliSense 和一切。另外,如果不进行大量反射,它并不能解决不知道通用对象的每个属性是什么的问题。
编辑:想法是能够在方法参数中确定对象的真实类型,然后将该对象转换为真实类型,而无需事先知道它。这只是一个简化的例子。盒装可能是错误的术语。
一个例子:
public class Program
{
static void Main(string[] args)
{
var container = new Container<Containee>(
new Containee
{
Property1 = Guid.NewGuid(),
Property2 = "I'm a property!",
Property3 = DateTime.Now
}
);
var boxed = (object)container;
var originalType = boxed.GetType();
// DOES NOT COMPILE: would like an operation like this
// EDIT: Request for more detail
var actualType = boxed as originalType;
actualType.Entity.Property2 = "But I like this better.";
}
}
public class Containee
{
public Guid Property1 { get; set; }
public string Property2 { get; set; }
public DateTime Property3 { get; set; }
}
public class Container<T>
{
public Container(T entity)
{
Entity = entity;
}
public T Entity { get; internal set; }
}
显然这不会编译,因为实际上并没有办法将其转换为变量。但是,我希望有一种方法可以获取对实际对象和类型的引用,或者至少是一种动态重新创建类型的方法。
我希望我忽略了一些简单的事情,或者是一种更好的方法来解决它。关键是能够将任何对象包装在容器中,然后弄清楚它是什么。
【问题讨论】:
-
我在您的代码中看不到任何装箱。您需要执行
var actualType = boxed as Container<Containee>;以使其可编译。 ` -
类的装箱不会发生。只有值类型(int 等)被装箱。您要查找的词是
casting。您已将 boxed 投射到对象。 -
我认为代码示例会妨碍您。他提到了一个事件处理程序,因此可以将其视为接收
object sender。他想知道在编译时是否有任何方法可以取回真实类型并享受智能感知的好处。 -
@Alex:那不是拳击。 @Richard 是正确的;装箱正在创建一个引用的包装器,以便可以将值类型存储在堆上。
-
我认为你的意思不是很清楚。您说您不想“失去 IntelliSense 和一切”,但是如果您在编写代码时不知道变量的类型,那么 IntelliSense 会给您什么?您不能将对象强制转换为未知类型,因为它没有实际效果。
标签: c# generics reflection event-handling boxing