Sunullo
301
2021-05-14 12:58:48
9
248

C# 자식 객체에서 부모 객체에 데이터 전달하는 방식을 객체지향에 위배되지않고 하는 방법이 있나요?


전달해야 될 타이밍을

상위객체에서 정하는게 아니라

하위객체에서 정해야되는 상황이라 get set 을 이용할 수도 없습니다.


하위 객체에서 for문을 돌리다가

마지막 타이밍에 상위 객체에 특정 데이터를 전달해야 되는 상황이 생겼습니다.


객체지향의 방식으로 어겨지 않고 해결 할 수 있는 방법이 있을까요?

이 경우 보통 어떤식으로 해결하나요?


0
  • 답변 9

  • HJOW
    3k
    2021-05-14 13:18:32

    오버라이드??


    1. 상위 클래스 코드에 getter 메소드를 virtual 키워드를 붙여 만들어 놓습니다.

        리턴값은 공란이나 null로 만들어 두어도 됩니다.


    2. 하위 클래스 코드에서 그 getter 메소드를 오버라이드합니다.

    (1번과 같은 이름의 메소드를 하위 클래스에 만들고 override 키워드를 붙입니다.)

    이 때 리턴값은 바로 상위 클래스 파일에서 필요로 하는 그 데이터를 리턴해야 합니다.


    3. 상위 클래스 코드에서 그 필요한 데이터를 필요로 할 때 저 메소드를 호출해서 가지오 오면 됩니다.

  • defult
    13k
    2021-05-14 13:20:25 작성 2021-05-14 13:23:49 수정됨
  • 캐티
    5k
    2021-05-14 13:33:02

    C#에서 base 키워드는 상속된 부모 객체로 이어지저. 수퍼클래스라고도 하는데 단어가 중요한건 아니고 일케 쓰면 좋을쩌여.

    예제 소스를 올려보시면 그렇게 해도 되는지 검토가 가능하겠쩌.

  • 안전라이딩
    1k
    2021-05-14 13:46:35

    뭘 원하는건지 모르겟지만..

    class ParentClass
    {
        protected SomeData data;
        public SomeData Data { get { return data; } }
    }
    
    class ChildClass : ParentClass
    {
        public async void GenerateData()
        {
            SomeData data = await Task.Run(() =>
            {
                var result = new SomeData();
    
                try
                {
                    // some for loop etc.
    
                    return result;
                }
                catch
                {
                    return null;
                }
            });
    
            base.data = data;
        }
    }


  • Sunullo
    301
    2021-05-14 13:51:31

    아..제가 질문을 잘못 올렸네요

    객체A에서 new로 객체 B를 생성했는데,

    B에서 특정 타이밍에 A에 정보를 전달하는 것을 여쭙고 싶었습니다;;

  • 안전라이딩
    1k
    2021-05-14 14:25:53

    defult 님이 언급한거 처럼 델리게이터 이요하거나 간단히 메시지 큐 두고 dispatch 시키는 구조를 두거나... 아니면 간단히 Akka 라이브러리 끌어다가 액터 모델 활용하거나 등등 이겠네요.

  • HJOW
    3k
    2021-05-14 14:26:05 작성 2021-05-14 14:26:45 수정됨

    A에 정보를 전달한다는 건

    A에 있는 뭔가가 값만 바뀌는게 아니라 뭔가 A에 있는 메소드가 실행이 된다거나 해야 하는 것인가요?



    정보를 전달한다고만 하면 알기 어렵습니다.

    정보만 전달할거면, A에 멤버변수 만들어놓고(public하게) B에서 특정 타이밍에 그 멤버변수에 값만 넣으면 끝입니다. 그러면 A에 있는 메소드에서 그 멤버변수로 값을 액세스할 수 있죠.

  • 안전라이딩
    1k
    2021-05-14 14:47:22

    akka 사용 간단한 예시를 적어보면.. 이런 느낌입니다.


    class Manager : ReceiveActor
    {
        // 일감 관리에 필요한 데이터
        // ...
    
        public Manager()
        {
            Receive<WorkReport>(m =>
            {
                // 결과를 관리 데이터에 반영
            });
            Receive<WorkRequest>(m =>
            {
                // 요구 사항에 따라 작업 배정
                Task.Run(() =>
                {
                    new Worker(Self).DoWork();
                });
            });
        }
    }
    
    class WorkReport
    {
        // 결과 보고
    }
    
    class WorkRequest
    {
        // 요구사항
    }
    
    class Worker
    {
        IActorRef manager;
    
        public Worker(IActorRef manager)
        {
            this.manager = manager;
        }
    
        public void DoWork()
        {
            Thread.Sleep(10000);
            manager?.Tell(new WorkReport()); // 작업 끝났으면 보고
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var akka = ActorSystem.Create($"{Guid.NewGuid()}");
            var manager = akka.ActorOf<Manager>();
    
            manager.Tell(new WorkRequest {
                // 작업 요구 사항
            });
        }
    }


  • CyanGlint
    1k
    2021-05-14 16:22:53

    .NET 쪽에서는 델리게이트, 좀더 흔한 용어로는 콜백이라고도 합니다.

    그런데 C#의 고전적인 delegate는 아무래도 쓰기 번거로운지라

    미리 만들어져있는 Action<T>, Func<T, TResult>를 제공하니 이걸 쓰면 됩니다.


    public class A
    {
        private B _b;
    
        public void RunB()
        {
            _b.Run(RunBCompleted);
    
            //또는 람다 식
            _b.Run(s =>
            {
                //두썸띵
            });
        }
    
        private void RunBCompleted(string s)
        {
            //두썸띵
        }
    }
    
    public class B
    {
        public void Run(Action<string> onComplete = null)
        {
            //두썸띵
            onComplete?.Invoke("ㅁㄴㅇㄹ");
        }
    }

    간단한 샘플

  • 로그인을 하시면 답변을 등록할 수 있습니다.