无法访问受保护的成员“object.MemberwiseClone()”
Posted
技术标签:
【中文标题】无法访问受保护的成员“object.MemberwiseClone()”【英文标题】:Cannot access protected member 'object.MemberwiseClone()' 【发布时间】:2011-01-02 15:39:39 【问题描述】:我正在尝试在我的自定义类上使用 .MemberwiseClone()
,但它会引发此错误:
Cannot access protected member 'object.MemberwiseClone()' via a qualifier of type 'BLBGameBase_V2.Enemy'; the qualifier must be of type 'BLBGameBase_V2.GameBase' (or derived from it)
这是什么意思?或者更好的是,我如何克隆 Enemy
类?
【问题讨论】:
【参考方案1】:在任何类X
中,您只能在X
的实例上调用MemberwiseClone
(或任何其他受保护的方法)。 (或者从X
派生的类)
由于您尝试克隆的 Enemy
类没有继承您尝试克隆的 GameBase
类,因此您会收到此错误。
要解决此问题,请将公共 Clone
方法添加到 Enemy
,如下所示:
class Enemy : ICloneable
//...
public Enemy Clone() return (Enemy)this.MemberwiseClone();
object ICloneable.Clone() return Clone();
【讨论】:
但我认为 MemberwiseClone 是 Object 的一种方法,afaik 所有的类都是从它派生的? 是的,但是你不能调用其他类的受保护方法,除非它继承自 you。否则,您只需从该类继承即可调用任何类上的任何受保护成员(包括MemberwiseClone
)。这将使protected
几乎毫无用处。
"protected" 是另一种说法:只有类本身知道何时 MemberwiseClone() 是正确的做法。它很少是,谷歌“深拷贝”。
ICloneable
在 Silverlight 5.0 中不可用
@PeterLee:你不需要使用ICloneable
。【参考方案2】:
不能直接使用 MemberwiseClone(),必须通过派生类实现(推荐)
但是,通过反射,你可以欺骗它:)
你可以对没有实现 ICloneable 的类使用这个小扩展:
/// <summary>
/// Clones a object via shallow copy
/// </summary>
/// <typeparam name="T">Object Type to Clone</typeparam>
/// <param name="obj">Object to Clone</param>
/// <returns>New Object reference</returns>
public static T CloneObject<T>(this T obj) where T : class
if (obj == null) return null;
System.Reflection.MethodInfo inst = obj.GetType().GetMethod("MemberwiseClone",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (inst != null)
return (T)inst.Invoke(obj, null);
else
return null;
【讨论】:
我不明白为什么MemberwiseClone 不公开......而且上面的“作弊”非常有用!竖起大拇指! 在 Silverlight 中,我得到了System.MethodAccessException was unhandled by user code: Message=Attempt by method 'ExtensionStaticClass.MemberwiseCloneEx<System.__Canon>(System.__Canon)' to access method 'System.Object.MemberwiseClone()' failed
在Silverlight中不能使用对私有成员的反射来保证安全,受微软限制,可以使用WCF序列化进行克隆
@Shaamaan:它不是公开的,因为由类所有者决定克隆应该如何工作;逐位克隆任意类不一定是安全的。例如,Thread
实例的按位克隆意味着什么?
这个作弊方法效果很好,但要注意使用反射对性能的影响。如果您要完成数千个(甚至更多)克隆操作,我不建议您使用此功能【参考方案3】:
这是一个允许克隆任何对象的扩展方法(请注意它并非在所有情况下都有效)
public static class Extra_Objects_ExtensionMethods
public static T clone<T>(this T objectToClone)
try
if (objectToClone.isNull())
"[object<T>.clone] provided object was null (type = 0)".error(typeof(T));
else
return (T)objectToClone.invoke("MemberwiseClone");
catch(Exception ex)
"[object<T>.clone]Faild to clone object 0 of type 1".error(objectToClone.str(), typeof(T));
return default(T);
【讨论】:
以上是关于无法访问受保护的成员“object.MemberwiseClone()”的主要内容,如果未能解决你的问题,请参考以下文章