【问题标题】:Reflection or Clone() C#反射或克隆() C#
【发布时间】:2013-06-28 14:01:07
【问题描述】:

一般来说,我应该在什么情况下使用反射与(浅)克隆方法?

如果我所有的类都有空白的构造函数,那么使用反射很好,或者编写更好的做法

Clone() 
{ 
    return new MyClass(); 
} 

需要它们的类的方法?

我可以看到Clone 方法的类型安全性更高,因为它可以在编译时检查,但哪个更快,什么时候使用反射更好?


更新。我不是在寻找特定问题的解决方案,而是为了学习更多理论来了解如何处理这种性质的问题。

但是,在某些情况下,我正在制作游戏,并且经常遇到这个问题。例如,游戏允许用户“放置”某些对象。当重复点击时,游戏需要创建多个实例(未知子类)。我想出了三个解决方案:

a) 让选择要放置的对象的菜单保存一个类型,并使用反射重复生成该类型。

b) 让菜单保存对象的一个​​实例,并使用反射创建新实例。 (现在可以用 MemberwiseClone 代替)

c) 让菜单保存对象的一个​​实例,并在放置第一个实例后使用 Clone 方法创建新实例。

我认为 C 是最好的,但我想了解原因。

我正在寻找的典型答案是这样的(请酌情扩展、更正和完整):

“克隆”方法通常不仅仅像您在问题中指出的那样调用 new();它将复制它正在克隆的实例的部分或全部属性。浅克隆复制有限数量的属性,而深度克隆复制所有属性。

如果您只需要创建特定类的新实例,最好使用 Object.MemberwiseClone()。

每次引用实例时都应该使用 Clone 方法,因为您知道该实例将具有 ICloneable 属性。

Activator.CreateInstance() 应仅在您没有对实例的引用时使用,例如当您从文本文件或 XXXXXXX 加载类信息时。

解决创建未知类的新实例问题的方法总是尝试通过类型安全的编译时方法(例如克隆)来完成,并且只在完全不可能的情况下使用反射。

作为优缺点总结:

克隆/MemberwiseClone

优点:在编译时检查为类型安全,在运行时不会使程序崩溃,在运行时速度更快 缺点:不能一直使用

反思

优点/缺点:与上述相反。

【问题讨论】:

  • 我认为在您的问题中您已经知道何时使用哪个。如果在编译时您知道要创建一个类型,请使用 new(),如果该类型是在运行时动态获取的,请使用反射。反射绝对慢。
  • 返回一个新的空对象的方法是怎样的clone方法?
  • 真的不清楚你在这里做什么。克隆一个对象不仅仅是针对该类型调用new。克隆一个对象意味着你克隆至少它的一些属性子集。此外,您甚至考虑在可克隆对象的Clone 方法上使用反射的驱动程序是什么?是你不想构建方法吗?
  • 很多人都说不要再偷懒了,写克隆方法,但是没有人告诉我什么时候应该使用反射?
  • 我的驱动程序正在了解最佳实践,以及 Activator 的用途

标签: c# reflection clone


【解决方案1】:

如果你真的想要一个浅拷贝,那么你可以很好地使用Object.MemberwiseClone 并实现ICloneable 接口。

public class Model : ICloneable
{
    public object Clone()
    {
        return MemberwiseClone();
    }
}

如果你真的想要,你可以使用反射来执行浅拷贝。我理解它是有利的,因为它是自动化的并且可以扩展以提供深层副本。但是,反射比 Object.MemberwiseClone() 慢,并且在部分信任环境中是不允许的。最初实现的代码也更多。 Read more here

【讨论】:

  • @Haighstrom 这能回答你的问题吗?
  • 它提供了一种更好的方法来完成我已有的工作,但我正在寻找关于何时应该和不应该使用反射的清晰解释。 IE。什么时候编译时不知道类型?
  • @Haighstrom 请详细说明您的问题,我会尽力回答。
  • 我在上面扩展了我的问题。任何进一步的帮助表示赞赏,然后我会将您的答案标记为回答问题。
  • 我实际上将您的答案标记为完整,因为我没有在手机上看到该链接,这几乎可以回答我想知道的问题。谢谢。
【解决方案2】:

创建一个类的新实例:

MyClass obj = new MyClass();

克隆一个实例:

MyClass clone = obj.Clone();

如果你想让你的类 Cloneable 你应该实现 ICloneable 接口:

public class MyClass : ICloneable
{
    public MyClass Clone()
    {
        MyClass clone = new MyClass();
        // Copy property values to clone-instance.
        return clone;
    }
}

我不明白你为什么要让反射参与创建新实例。

【讨论】:

  • 我知道如何编写克隆方法。我不知道为什么我要写 MyThing.Clone() 而不是 Activator.CreateInstance (MyThing.getType ())。或者当需要反思时。
猜你喜欢
  • 2011-02-08
  • 2016-01-27
  • 1970-01-01
  • 2018-08-31
  • 2017-07-12
  • 2015-03-27
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多