문제

C#의 메소드를 C#로 선언하는 방법을 어떻게 선언합니까?

(즉, C ++의 개인 가상 기능처럼)

편집하다
private virtual "내 행동을 수정하는 방법은 있지만,이 기능을 직접 호출 할 수는 없습니다 (기본 클래스 만 할 수있는 Arcane Invocations가 필요하기 때문에 여전히이 함수를 직접 호출 할 수 없습니다."

그래서 그것을 명확히하기 위해 : C#에서 그 표현에 가장 적합한 표현은 무엇입니까?

도움이 되었습니까?

해결책

C#은 C ++보다 "개인"에 대한 강력한 보증을합니다. C ++에서는 실제로 개인 가상 메소드를 무시할 수 있습니다. 그러나 이는 기본 클래스의 코드가 파생 클래스에서 코드를 실행할 수 있음을 의미합니다. 개인 방법이 진정으로 사적이며 같은 클래스의 방법에 의해서만 호출 될 수 있다는 약속을 어기는 것입니다.

여기서 도움이되지 않는 것은 C ++가 가상 키워드를 반복 할 필요가 없다는 것입니다. 이와 같은 미스터리를 리버스 엔지니어링하는 미스터리로 이어집니다.

#include "stdafx.h"
#include <iostream>

class Base {
private:
    virtual void Method() = 0;
public:
    void Test() {
        Method();
    }
};
class Derived : public Base {
private:
    void Method() { std::cout << "Who the heck called me?"; }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* p = new Derived;
    p->Test();
}

개인 상속에 대한 가능한 역할이 있다는 데 동의합니다. C# 언어 디자이너는 아니오! 그렇지만.

다른 팁

"실제 클래스 내에서"만 호출 할 수 있어야한다고 말할 때 기본 클래스 또는 파생 클래스를 의미합니까? 이들 중 어느 것도 그 자체로는 가능하지 않습니다. 가장 가까운 것은 보호 된 방법을 사용하는 것입니다. 즉, 선언 클래스, 파생 클래스 및 추가 유래 클래스에서 호출 할 수 있습니다.

개인 회원은 아동 수업에 보이지 않습니다. 보호 된 가상이 원하는 방식으로 수행 할 것이라고 생각합니까?

업데이트:

여기에는 C#내의 상속 및 재정의 기능으로 무엇을 할 수 있는지에 대한 설명이 더 자세히 설명되어 있습니다. 나는 다소 의미있는 예를 사용하려고 노력했지만, 그것이 열악한 클래스 디자인이라는 것을 이해했으며, 이런 식으로 설명 된 클래스를 구현하는 것은 권장하지 않을 것입니다. 그러나 아마도 이것이 수용 가능한 방식으로 원래 문제를 해결할 수있는 방법을 제공하기를 바랍니다. 콘크리트 클래스가 멤버를 호출하는 것을 막는 방법은 없지만, 어쨌든 구조가 이와 같은 경우 문제가되지 않을 것입니다.

public abstract class Animal
{
    public void DisplayAttributes()
    {
        Console.WriteLine(Header());
        Console.WriteLine("Name: " + Name());
        Console.WriteLine("Legs: " + Legs());
        Console.WriteLine();
    }

    protected virtual int Legs()
    {
        return 4;
    }

    private string Header()
    {
        return "Displaying Animal Attributes";
    }

    protected abstract string Name();
}

public class Bird : Animal
{
    protected override string Name()
    {
        return "Bird";
    }

    protected override int Legs()
    {
        return 2;
    }
}

public class Zebra : Animal
{
    protected override string Name()
    {
        return "Zebra";
    }
}

public class Fish : Animal
{
    protected override string Name()
    {
        return "Fish";
    }

    protected override int Legs()
    {
        return 0;
    }

    private string Header()
    {
        return "Displaying Fish Attributes";
    }

    protected virtual int Gils()
    {
        return 2;
    }

    public new void DisplayAttributes()
    {
        Console.WriteLine(Header());
        Console.WriteLine("Name: " + Name());
        Console.WriteLine("Gils: " + Gils());
        Console.WriteLine();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Bird bird = new Bird();
        bird.DisplayAttributes();
        //Displaying Animal Attributes
        //Name: Bird
        //Legs: 2

        Zebra zebra = new Zebra();
        zebra.DisplayAttributes();
        //Displaying Animal Attributes
        //Name: Zebra
        //Legs: 4


        Fish fish = new Fish();
        fish.DisplayAttributes();
        //Displaying Fish Attributes
        //Name: Fish
        //Gils: 2

        List<Animal> animalCollection = new List<Animal>();
        animalCollection.Add(bird);
        animalCollection.Add(zebra);
        animalCollection.Add(fish);

        foreach (Animal animal in animalCollection)
        {
            animal.DisplayAttributes();
            //Displaying Animal Attributes
            //Name: Bird
            //Legs: 2

            //Displaying Animal Attributes
            //Name: Zebra
            //Legs: 4

            //Displaying Animal Attributes
            //Name: Fish
            //Legs: 0
            //*Note the difference here
            //Inheritted member cannot override the
            //base class functionality of a non-virtual member
        }
    }
}

이 예에서 Bird, Zebra 및 Fish는 모두 이름과 다리 방법을 부를 수 있지만,이 예제에서는 반드시 그렇게하는 데 도움이되지는 않습니다. 또한, 물고기에 의해 도시 된 바와 같이, displayAttributes ()는 콘크리트 파생 클래스의 인스턴스에 대해 수정 될 수있다; 그러나 Foreach 루프에서와 같이 동물을 볼 때 실제 동물 유형에 관계없이 기본 클래스가 행동을 표시합니다. 이것이 당신이 복제하려는 기능 유형을 발화하는 데 도움이되기를 바랍니다.

대의원의 사용을 고려 했습니까? 파생 클래스가 일부 보호 속성을 통해 대의원을 설정하거나 생성자에게 전달할 수 있습니다. 또한 기본 클래스의 개인 메소드 인 내부 구현에 대의원을 기본값으로 기본값을 할 수도 있습니다.

VBOCTOR가 이미 언급 한 내용의 예는 다음과 같습니다.

public class Base
{
    private Func<Base, int> func;
    protected void SetFunc(Func<Base, int> func)
    {
        this.func = func;
    }

    private void CallFunc()
    {
        if (func != null)
        {
            var i = func(this);
        }
    }
}

public class Sub : Base
{
    private void DoFuncyStuff()
    {
         this.SetFunc(b => 42);
    }
}

개인이 되려면 왜 필요한가요? 보호 된 것은 여기에서 충분해야합니다. 서브 클래스 저자에게 전화 할 수없는 코드를 작성하도록 요청합니다. 이것이 무엇을 성취합니까? 어쨌든 그 코드를 사용할 수 있습니다.

내가 당신의 질문을 읽을 때, 당신은 두 가지를 의미 할 수 있습니다.

첫째, 클래스 A에서 기능을 원한다면 아동 클래스 B에서 재정의 할 수 있지만 외부 클래스에는 보이지 않는 경우

public class ClassA
{
  protected virtual ReturnType FunctionName(...) { ... }
}

public class ClassB
{
  protected override ReturnType FunctionName(...) { ... }
}

둘째, 구현 클래스가 함수를 정의하도록 강요하려는 경우 :

public abstract class ClassA
{
  protected abstract ReturnType FunctionName(...);
}

public class ClassB
{
  protected override ReturnType FunctionName(...) { ... }
}

당신이 C#을 파고 들고있는 경우에도 볼 수있는 또 다른 개념은 부분 클래스입니다. 이것은 컴파일 시간에 결합되어 동일한 어셈블리에서 하나의 클래스를 만들기 위해 두 개의 소스 파일을 결합한다는 아이디어입니다.

File 1:

public partial class ClassA
{
    private ReturnType FunctionName(...);
}  

File 2:

public partial class ClassA
{
  //actual implimentation
  private ReturnType FunctionName(...){ ... }; 
}

LINQ2SQL 파일, EDM, Winforms 등과 같은 설계된 파일을 처리 할 때를 제외하고는 부분이 널리 사용되지 않습니다.

당신이 의도 한대로 작동하지 않을 것이라고 생각하지만, 당신을 위해 의사 코드를 스케치하겠습니다.

public interface BaseClassFunction {
    void PleaseCallMe();
}

public class BaseClass {
    private BaseClassFunction fn;
    public BaseClass(BaseClassFunction fn) {
        this.fn = fn;
    }
    private CallMe() {
        fn.PleaseCallMe();
    }
    public PublicCallMe() {
        CallMe();
    }
}

private class DerivedClassFunction : BaseClassFunction {
    void PleaseCallMe() { ... do something important ... }
}

public class DerivedClassFunction {
    public DerivedClassFunction() : BaseClass(new DerivedClassFunction()) {
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top