将盒装对象投射回原始类型

问题描述

|| 我希望对此有两个答案之一,要么是不可能的,要么是非常简单的,而我却忽略了显而易见的Google查询。 潜在的问题是我有一个通用对象通过“ 0”传递,该对象将对象装箱并混淆了真正的类型。只有在运行时,我才知道对象是什么。 诚然,ѭ1关键字可以解决此问题,但是我想避免失去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; }
}
显然,这不会编译,因为实际上并没有将其转换为变量的方法。但是,我希望有一种方法可以获取对实际对象和类型的引用,或者至少有一种动态重新创建类型的方法。 我希望可以忽略一些简单的事情,或者总体上更好的解决方法。关键是要能够将任何对象包装在容器中,并在以后弄清楚它是什么。     

解决方法

           这个想法是为了能够确定方法参数中对象的真实类型 这很容易(而且您已经在做)。
Type actualType = param.GetType();
这将为您提供对象的实际具体类型   然后将该对象转换为真实类型 这是事情有点偏离轨道的地方。 C#中的强制转换运算符(使用这种运算符被人们称为\“ casting \”)可以做两件事: 通过将转换应用于现有对象,使用特定于类型的显式转换来创建新对象(请注意,这是已创建的新引用;原始对象的类型永远不会更改) 允许开发人员将对象引用为在其继承层次结构中处于与当前提供的层次不同的类型的类型(或在层次结构中低于当前引用的类型上实现的接口) 在您的情况下,第一种选择是正确的;像所有运算符一样,强制转换运算符也不是多态的。也就是说,仅当运算符是在要引用的类型上定义的,而不是在要引用的对象上定义时,才应用。如果您想对此做进一步的澄清,请告诉我,但是我认为这与您的问题没有任何关系,因此,除非另行询问,否则我将不作进一步讨论。 第二个选项是可以实际应用到您的唯一选项,但是请考虑要这样做的两个唯一原因: 这样您就可以将对象称为特定的具体类型,其级别比当前提供的级别低(在您的情况下,您的对象是
object
,因此它的数量已经足够多了) 这样您就可以将对象引用为层次结构中较高的类型,从而可以绕过隐藏(但不能覆盖)的成员。 (绝大多数演员表都是出于原因1) 您想要使用这些选项之一的原因是,您可以拥有一个强类型的对象并使用在该类型上定义的各种成员。但是所有这些仅适用于编写代码时知道的类型。强制转换为在编译时未知的类型是没有意义的,因为强制转换对实际对象没有任何作用(它是并且应该保留其真实类型;唯一改变的是引用对象的变量类型)。 如果您可以提供一个进一步说明您实际要做什么的示例(根据您的期望或期望它能正常工作完成代码),我也许可以提供一些更接近实际的模型您想要什么,但是正如我所描述的,这是我所能获得的。     ,        首先:不是\“拳击\”。装箱适用于值类型,例如
struct
s。 第二:您可能需要的是: 编译时反射,C#没有 动态代码生成,您可以用
Reflection.Emit
(痛苦地)完成。 第三:您的示例代码是
variable1 as variable2
,这实际上没有任何意义。 :\\之后您打算做什么?也许有更好的方法。     ,
var actualType = boxed as originalType;
就像我们在同一页面上一样,让我解释为什么这是不可能的。
var
是一个编译时结构。等同于直接声明正确类型的变量。除了易于输入之外,它的主要用途是用于匿名类型(隐含的是没有名称)。 无论如何,要解决您的问题,最好的选择是使用动态代码生成,以with6ѭ或
CodeDom
使用(如果您不懂ILASM,后者更容易理解,但要慢得多)。 根据您实际想要做的事情,您可能可以摆脱类似
if(someObject is Container<Containee>) {
     var container = (Container<Containee>)someObject;
     //...
}
但是,如果您能指望任何类型的话,那么……祝您好运。     ,           根本的问题是我有一个   通用对象通过   装箱对象的EventHandler和   混淆真实类型;仅在   运行时我知道对象是什么。 如果仅在运行时知道类型,您要如何处理?您不能调用任何特定的类方法,因为无论如何您都不知道确切的类型,除非所有对象共享一些可以作为接口提取的方法集。 基本上,您有几种选择: 使用
is
对不同类型执行不同的操作:
object value = GetValue ();
if (value is Program)
    ((Program)value).Run ();
else if (value is Animal)
    ((Animal)value).Run ();
如果所有可能的类型都应该共享一组操作,请使用一个接口:
object value = GetValue ();
IRunnable runnable = (IRunnable)value;
runnable.Run ();
重新说明您的问题,并在完成“神奇的转换”后扩展示例,说明其工作方式。这将使我们了解您要完成的工作。     ,        您可以使用
dynamic
dynamic actualType = boxed;
actualType.Entity.Property2 = \"But I like this better.\";
这应该编译并起作用。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...