C# 无法访问受保护的成员';object.MemberwiseClone()';

C# 无法访问受保护的成员';object.MemberwiseClone()';,c#,clone,C#,Clone,我试图在我的自定义类上使用.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) 这是什么意思?或者更好的是,我如何克隆一个敌人

我试图在我的自定义类上使用
.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)

这是什么意思?或者更好的是,我如何克隆一个
敌人
类?

在任何类
X
中,您只能在
X
的实例上调用
MemberwiseClone
(或任何其他受保护的方法)。(或从
X
派生的类)

由于您尝试克隆的
敌人
类没有继承您尝试克隆它的
游戏库
类,因此您会遇到此错误

要解决此问题,请将公共的
克隆
方法添加到
敌人
,如下所示:

class Enemy : ICloneable {
    //...
    public Enemy Clone() { return (Enemy)this.MemberwiseClone(); }
    object ICloneable.Clone() { return Clone(); }
}
  • 您不能直接使用MemberwiseClone(),必须通过派生类实现它(推荐)
  • 但是,通过反思,你可以欺骗它:)
  • 您可以将此litle扩展用于未实现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;
    }
    
    //
    ///通过浅复制克隆对象
    /// 
    ///要克隆的对象类型
    ///要克隆的对象
    ///新对象引用
    公共静态T CloneObject(此T对象),其中T:class
    {
    if(obj==null)返回null;
    System.Reflection.MethodInfo inst=obj.GetType().GetMethod(“MemberwiseClone”,
    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    如果(inst!=null)
    返回(T)inst.Invoke(obj,null);
    其他的
    返回null;
    }
    

这里有一个扩展方法,允许克隆任何对象(使用时要注意,它并非在所有情况下都有效)

公共静态类额外对象扩展方法
{
公共静态T克隆(此T对象克隆)
{
尝试
{
if(objectToClone.isNull())
“[object.clone]提供的对象为null(type={0})”。错误(typeof(T));
其他的
return(T)objectToClone.invoke(“MemberwiseClone”);
}
捕获(例外情况除外)
{
“[object.clone]未能克隆类型为{1}的对象{0}”。错误(objectToClone.str(),typeof(T));
}
返回默认值(T);
}   
}

但我认为MemberwiseClone是一个Object方法,所有类都是从它派生的?是的,但除非它从您继承,否则您不能调用其他类的受保护方法。否则,只需从任何类继承,就可以在任何类上调用任何受保护的成员(包括
MemberwiseClone
)。这将使受保护的
几乎毫无用处。“protected”是另一种说法:只有类本身知道何时应该执行MemberwiseClone()。谷歌的“深度复制”很少见。
ICloneable
在Silverlight 5中不可用。0@PeterLee:您不需要使用
iClonable
。我无法理解MemberwiseClone为什么不是公共的。。。而上面的“作弊”是非常有用的!竖起大拇指!在Silverlight中,我得到
System.MethodAccessException未经用户代码处理:Message=ExtensionStaticClass.MemberwiseCloneEx(System.\uu Canon)”方法尝试访问“System.Object.MemberwiseClone()”失败
在Silverlight中,出于安全考虑,受microsoft限制,无法使用对私有成员的反射,您可以将WCF序列化用于clone@Shaamaan:它不是公共的,因为由类所有者决定克隆应该如何工作;对任意类进行逐位克隆并不一定安全。例如,
线程
实例的按位克隆意味着什么?这种欺骗很有效,但要注意反射的使用对性能的影响。如果你有成千上万(甚至更多)的克隆操作要做,我不建议你使用这个功能
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);
    }   
}