문제

같은 유형의 2 개의 개체가 있으며 한 상태를 다른 상태로 얕게 복사하고 싶습니다. C ++에서 나는 memcpy를 가지고 있습니다. C#에서 어떻게 할 수 있습니까? MemberWiseClone ()은 새 개체를 생성하고 반환하기 때문에 충분하지 않으며 기존 객체에 복사하는 것을 좋아합니다. 나는 반사를 사용하는 것을 생각했지만 생산 코드에는 너무 느리기 때문에 두려워합니다. 또한 .NET 시리얼 라이저 중 하나를 사용한다고 생각했지만 기존 객체를 설정하는 대신 객체를 생성한다고 생각합니다.

내 유스 케이스 :

인스턴스 중 하나 (이 템플릿으로 만든 객체)에 의해 업데이트되어야하는 템플릿 객체 (class not struct)가 있습니다.

어떤 아이디어?

도움이 되었습니까?

해결책

편집] 설명과 관련하여 : 내가 이해 한대로, 당신은 n 객체를 가지고 있으며, 각각은 템플릿 객체에 대한 (직접) 참조가 있습니다. 모든 객체가 이러한 변경 사항을 "참조"하도록 템플릿에 다시 쓰려고합니다.

제안 : 템플릿 브로커의 Imlement.

class TemplateProvider
{
   public MyData Template { get; set; }
}

템플릿을 전달하는 대신 템플릿 제공 업체를 객체에 전달하십시오.

구성 요소의 구문을 간단히 사용하려면 (개인/내부?) 속성을 추가 할 수 있습니다.

MyData Template { get { return m_templateProvider.Template; } }
void UpdateTemplate() { m_templateProvider.Template = 
                            (MyData) this.MemberwiseClone(); }

템플릿 제공 업체는 또한 멀티 스레드 시나리오에서 잠금을 단순화합니다.


요컨대, 당신이 직접하지 않는 한 아무 방법도 없습니다. 그러나 어쨌든 모든 속성을 무시하면 새 개체를 만들지 않겠습니까?

memcopy 또한 유사한 낮은 수준의 구성은 환경에 의해 보장을 훼손하기 때문에 지원되지 않습니다.

스트러크에 대한 얕은 사본은 과제에 의해 이루어집니다. 수업의 경우 MemberwiseClone 그렇게하는 방법이지만, 당신이 말하는 것처럼 그것은 새로운 객체를 만듭니다.

이를위한 내장은 없으며, 잠재적으로 캡슐화를 깨뜨리기 때문에 어쨌든주의해서 사용해야합니다.

반사를 사용하여 일반적인 루틴을 구축 할 수 있지만 작동 여부는 클래스 자체에 따라 다릅니다. 그렇습니다. TI는 비교할 수 있습니다.

남은 것은 사용자 정의 인터페이스로 지원하는 것입니다. 인터페이스를 확인하고 사용하는 일반적인 "얕은 사본"루틴을 제공 할 수 있으며, 그렇지 않은 경우 반사로 돌아갑니다. 이렇게하면 기능을 일반적으로 사용할 수 있으며 성능이 나중에 중요한 클래스를 최적화 할 수 있습니다.

다른 팁

~ 안에 C# (그리고 내 C++ 또한), 모든 회원이 서로 동등한 한 "새 개체"와 "기존 객체의 사본"사이에는 차이가 없습니다.

주어진:

Int32 a = 5;

, 두 작업 모두 :

Int32 b = 5;
Int32 b = a;

동일한 결과를 산출하십시오.

언급 된 바와 같이 MSDN 참조:

Memberwiseclone 메소드는 새 개체를 만들어 현재 객체의 비 종종 필드를 새 개체에 복사하여 얕은 사본을 만듭니다.

필드가 값 유형 인 경우, 필드의 비트 바이트 사본이 수행됩니다.

필드가 참조 유형 인 경우 참조가 복사되지만 참조 된 객체는 그렇지 않습니다. 따라서 원래 물체와 클론은 동일한 객체를 나타냅니다.

, 즉, 그것은 동일합니다 memcpy() 안에 C++

나는 당신이 다음과 같은 일을 할 수 있다고 생각합니다.

YourObjectType A = new YourObjectType();
YourObjectType B = a.MemberwiseClone();

이렇게하면 Memberwiseclone 메소드 내부에 새 객체가 생성됩니다. A B 객체가 참조합니다. 나는 그것이 당신의 목적을 제공한다고 생각합니다.

모든 의도와 목적을 위해 한 구조물을 다른 구조물에게 할당하는 것은 바로 그거죠 처럼 memcpy 포드 객체의 C ++에서.

상황에 이것이 적용되지 않는다고 생각되면 C ++ 코드가 표준 정보가 아니라고 확신 할 수 있습니다 (즉, 정의되지 않은 동작의 형태로 버그가 포함되어 있음). 명시 해주세요 (질문에서) 달성하고자하는 효과. 이것은 다른 언어로 정의되지 않은 행동을 복제하는 것에 대해 이야기하는 것보다 더 유용합니다.

namespace WindowsFormsApplication7
{

    [Serializable] // just put this in your class
    class Mate
    {
        public string SomeProperty { get; set; }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            var mA = new Mate();
            mA.SomeProperty = "Hey";

            var vf = new BinaryFormatter();
            var ns = new MemoryStream();
            vf.Serialize(ns, mA);
            byte[] vytes = ns.ToArray();


            var vfx = new BinaryFormatter();
            var nsx = new MemoryStream();            
            nsx.Write(vytes, 0, vytes.Length);
            nsx.Seek(0, 0);
            var mB = (Mate)vfx.Deserialize(nsx);

            mA.SomeProperty = "Yo";

            MessageBox.Show(mA.SomeProperty); // Yo
            MessageBox.Show(mB.SomeProperty); // Hey
        }
    }
}
namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var dt = new DataTable();
            dt.Columns.Add("lastname", typeof(string));
            dt.Columns.Add("firstname", typeof(string));

            dt.Rows.Add("lennon", "john");
            dt.Rows.Add("mccartney", "paul");


            var ms = new MemoryStream();
            var bf = new BinaryFormatter();
            bf.Serialize(ms, dt);
            byte[] bytes = ms.ToArray();



            var bfx = new BinaryFormatter();
            var msx = new MemoryStream();
            msx.Write(bytes, 0, bytes.Length);
            msx.Seek(0, 0);


            // doesn't just copy reference, copy all contents
            var dtx = (DataTable)bfx.Deserialize(msx);


            dtx.Rows[0]["lastname"] = "Ono";


            // just copy reference
            var dty = dt;

            dty.Rows[0]["lastname"] = "Winston";

            MessageBox.Show(dt.Rows[0]["lastname"].ToString()); // Winston
            MessageBox.Show(dtx.Rows[0]["lastname"].ToString()); // Ono
            MessageBox.Show(dty.Rows[0]["lastname"].ToString()); // Winston

        }
    }
}

나는 새로 생성 된 객체를 사용할 수 없습니다. 주형 인스턴스 중 하나의 상태에 따라 변경 될 객체 (즉, 해당 템플릿으로 만든 인스턴스)

내가 생각할 때 - memberwiseclone () 메소드 구현의 코드를보고 Microsoft가 내 질문을 어떻게 해결했는지 확인하는 것은 매우 흥미 롭습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top