C#: 공동 및 역변

13558 단어 C#협동과 역변
 , , , 。

할당 호환성


그 전에'부치 호환성'을 알아보면 파생류 대상이'기류 대상'에게 부치할 수 있고 그렇지 않으면 안 된다.이 개념을 이해하면 나중에 시간이 지나면 헷갈릴 수 있지만 사실 방문의 안전성으로만 이해하면 쉽게 잊혀지지 않는다.파생류는 기류에서 물려받은 것이고 자신의 개인적인 것도 있다.
  • 파생류 대상 Dog에 기본 대상 Animal에 값을 부여하고 Animal 대상이 접근할 수 있는 동물 속성은 Dog 대상에서 모두 접근할 수 있다.
  • 그런데 반대로 애니멀 대상을 Dog 대상에게 부여하면 Dog 대상이 접근할 수 있는 메모리가 애니멀 대상보다 훨씬 많다. 예를 들어 개의 코가 영리하고 동물이 꼭 영리한 것은 아니다. 이때 Dog 대상으로 개다리라는 속성을 방문했는데 결과적으로 Dog 대상에게 값을 부여한 애니멀 개다리라는 속성이 없다. 아마도 방문한 것은 소머리가 말주둥이에 맞지 않고 엉망진창일 것이다.이때 이 메모리가 남의 Rabbit 대상에 속한다면 다른 고양이와 개가 Rabbit를 어떻게 생각하게 하든지 대상도 아니다.

  • 그래서 안전성에서 볼 때 개다리가 토끼다리가 되지 않도록 토끼집(메모리)의 안전을 지키기 위해 기류는 파생류에 값을 부여할 수 없다.

    협동하여 변화시키다


    먼저 이전 코드의 일치된 부분을 보십시오:
    class        Animal {
          public  int  Legs = 4;}
    class  Dog : Animal {
           }
    delegate T Factory<out T>( );
    
    class Program
    {
         
    	static Dog MakeDog()
    	{
         
    		return new Dog();
    	}
    	static void main()
    	{
         
    		Factory<Dog>    dogMaker     = MakeDog;
    		Factory<Animal> animalMaker  = dogMaker;
    		Console.WriteLine(animalMaker().Legs.ToString());
    	}
    } 
    

    어떻게 보면 DogMaker가 animalMaker에 값을 부여하는 것은 파생류가 기류에 값을 부여하는 것이 아니겠습니까?놀랄 게 뭐 있어. 사실 이곳의 주요 모순은 부치 호환성에 있는 것이 아니라 FactoryFactory는 같은 유형이 아니기 때문이야. Dog Maker와 animal Maker는 Dog과 Animal 종류가 아니야.여기서 DogMaker 에이전트의 함수는 Dog 대상을 되돌려주고 animalMaker 에이전트의 함수는 Animal 대상을 되돌려준다. 되돌려주는 값의 부여 호환성animalMaker = dogMaker은 완전히 가능하다. 유일한 모순은 각각 FactoryFactory 두 의뢰류에 속하는데 두 등급이 어떻게 서로 바뀌는지 사람과 개는 서로 바꿀 수 없다는 것이다(사람과 개는 모두 동물에 속하지만 != ( ) .이때 out 키워드는 관건적인 역할을 한다. out 키워드는 컴파일러에게 내가 가지고 있는 이 동생의 매개 변수는 출력에만 사용되는 것이니 FactoryFactory 이 두 녀석은 상관하지 마라. 내가 데리고 있는 동생이 부치 호환성에 부합하기만 하면 된다.

    역변

    class Animall {
          public int NumberOfLegs = 4; }
    class Dog : Animal{
         }
    class Program
    {
         
    	delegate void Action	<in T>(T a);
    	static void ActionAnimal(Animal a) {
          Console.WriteLine(a.NumberOfLegs); }
    	static void main()
    	{
         
    		Action1<Animal> act1 = ActOnAnimal;
    		Action1<Dog> dog1 = act1;
    		dog1(new Dog());
    	}
    }
    
    static void ActionAnimal(Animal a) { Console.WriteLine(a.NumberOfLegs); }이라는 코드를 보면 협변과 반대로 협변은 출력 매개 변수만 사용하는 것을 강조하는데 여기의Animal a는 어쩔 수 없이Console.WriteLine(a.NumberOfLegs);에 사용되고 여기는 입력에만 사용된다.그래서 이 in 키워드는 관건적인 역할을 한다. 이것은 컴파일러에게 내가 데리고 있는 동생은 입력 매개 변수만 사용한다. 너는act1과dog1이 같은 유형이든 상관없다. 너는 이 두 의뢰 에이전트의 함수의 입력 매개 변수가 부수 호환성에 부합되는지 여부만 있으면 된다.

    총결산


    인터넷에 이런 말이 있는데 나는 그다지 옳지 않다고 생각한다.
    하위 클래스에서 하위 클래스로 변환하는 것은 협동 변환입니다. 반환값 형식에 사용되며 out 키워드로 하위 클래스에서 하위 클래스로 변환됩니다. 역변환 방법에 사용되는 매개 변수 형식은 in 키워드로 변환됩니다.
    위의 두 단락의 코드를 보면 협동이든 역변이든 그 본질은 클래스의 부수 호환성에 부합되어야 한다.
  • 협동변화 중의 매개 변수는 출력 매개 변수만 하고 dogMaker는 Dog을 되돌려준다. 이것은 animalMaker가 곧 되돌아올 Animal에 값을 부여한다. 즉, 파생 클래스는 기본 클래스에 값을 부여하고 값 부여 호환성에 부합한다.
  • 		Factory<Dog>    dogMaker     = MakeDog;
    		Factory<Animal> animalMaker  = dogMaker;
    		Console.WriteLine(animalMaker().Legs.ToString());
    
  • 역변 중의 매개 변수는 입력 매개 변수만 하고 dog1(new Dog()) = act1(new Dog())= ActOnAnimal(new Dog()); 여기 new의 Dog는Animal로 전환되며 부치 호환성에 부합된다.
  • 		Action1<Animal> act1 = ActOnAnimal;
    		Action1<Dog> dog1 = act1;
    		dog1(new Dog());
    

    그리고 입력 매개 변수와 출력 매개 변수를 동시에 할 수 있을까요?다음 코드를 보십시오.
    class        Animal {
          public  int  Legs = 4;}
    class  Dog : Animal {
           }
    delegate T Factory<T>(T t );
    
    class Program
    {
         
    	static Dog MakeDog(Dog dog)
    	{
         
    		Console.WriteLine($"{dog.legs}");
    		return new Dog();
    	}
    	static Animal MakeAnimal(Animal animal)
    	{
         
    		Console.WriteLine($"{animal.legs}");
    		return new Animal();
    	}
    	static void main()
    	{
         
    		Factory<Dog>    dogMaker     = MakeDog;
    		Factory<Animal> animalMaker  = dogMaker;// Factory Factory 
    		
    		Factory<Animal> a            = MakeAnimal;
    		Factory<Dog>    b            = a;// Factory Factory 
    		Console.WriteLine(animalMaker().Legs.ToString());
    	}
    } 
    

    이 코드는 컴파일을 통과할 수 없다. 이렇게 수정한 후에Factory가 의뢰한 범용 매개 변수 t는 입력 값과 반환 값을 한다. 이때 어느 쪽에서 어느 쪽에 값을 부여하든지 기본 클래스 대상이 파생 클래스 대상에게 값을 부여하는 난감한 장면을 만날 수 있다. 전송된 매개 변수가 아니라 되돌아오는 값에서 발생한다.이로써 아웃 (출력 매개 변수만) 과 in (입력 매개 변수만) 이라는 두 키워드가 왜 필요한지 알 수 있다. 왜냐하면 전환할 수 있다면 값 호환성에 부합해야 하기 때문이다.물론 이 두 키워드를 주지 않으면 부치 호환성에 딱 맞을까?나는 컴파일러가 그렇게 지능적이지 않다고 생각한다. 네가 그것을 알려주지 않았다면, 컴파일러는 판단할 수 없었을 것이다.
    그런데 여기서 궁금한 게 하나 더 있어요. 아웃과 in으로 파라미터를 한정했어도 FactoryFactory는 같은 유형이 아니에요. 이 문제가 먼저 있어요.

    좋은 웹페이지 즐겨찾기