C #에서 추상 정적 메서드를 사용할 수없는 이유는 무엇입니까?
나는 최근에 약간의 공급자 와 협력 해 왔으며 , 추상 정적 메소드를 가진 추상 클래스를 갖고 싶었던 흥미로운 상황을 발견했습니다. 주제에 대한 몇 가지 게시물을 읽었으며 의미가 있지만 명확한 설명이 있습니까?
정적 메소드는 인스턴스화 되지 않으며 객체 참조없이 사용할 수 있습니다.
정적 메소드에 대한 호출은 객체 참조가 아닌 클래스 이름을 통해 수행되며이를 호출하기위한 IL (Intermediate Language) 코드는이를 정의한 클래스의 이름을 통해 추상 메소드를 호출합니다. 사용한 수업.
예를 보여 드리겠습니다.
다음 코드로
public class A
{
public static void Test()
{
}
}
public class B : A
{
}
B.Test를 호출하면 다음과 같이됩니다.
class Program
{
static void Main(string[] args)
{
B.Test();
}
}
Main 메서드 내부의 실제 코드는 다음과 같습니다.
.entrypoint
.maxstack 8
L0000: nop
L0001: call void ConsoleApplication1.A::Test()
L0006: nop
L0007: ret
보시다시피 A.Test는 B.Test가 아닌 A 클래스이므로 코드를 작성할 수는 있지만 A.Test가 호출됩니다.
델파이 에서처럼 객체가 아닌 유형을 참조하는 변수를 만들 수있는 클래스 유형 이 있다면 가상 및 추상 정적 메소드 (및 생성자)에 더 많이 사용되지만 사용할 수는 없으며 따라서 정적 호출은 .NET에서 비 가상적입니다.
IL 디자이너가 코드를 컴파일하여 B.Test를 호출하고 런타임에 호출을 해결할 수 있음을 알고 있지만 여전히 클래스 이름을 작성해야하므로 가상적이지는 않습니다.
가상 메소드와 추상 메소드는 런타임에 다양한 유형의 오브젝트를 포함 할 수있는 변수를 사용하는 경우에만 유용하므로 변수에있는 현재 오브젝트에 대해 올바른 메소드를 호출하려고합니다. 정적 메소드를 사용하면 어쨌든 클래스 이름을 거쳐야하므로 호출 할 정확한 메소드는 컴파일 타임에 알 수 없으며 변경되지 않기 때문에 알 수 있습니다.
따라서 .NET에서는 가상 / 추상 정적 메서드를 사용할 수 없습니다.
정적 메소드는 상속되거나 재정의 될 수 없으므로 추상적 일 수 없습니다. 정적 메소드는 클래스의 인스턴스가 아닌 유형에 정의되므로 해당 유형에서 명시 적으로 호출해야합니다. 따라서 자식 클래스에서 메소드를 호출하려면 해당 이름을 사용하여 호출해야합니다. 이것은 상속을 무의미하게 만듭니다.
정적 메소드를 잠시 상속받을 수 있다고 가정하십시오. 이 시나리오를 상상해보십시오.
public static class Base
{
public static virtual int GetNumber() { return 5; }
}
public static class Child1 : Base
{
public static override int GetNumber() { return 1; }
}
public static class Child2 : Base
{
public static override int GetNumber() { return 2; }
}
Base.GetNumber ()를 호출하면 어떤 메소드가 호출됩니까? 어떤 값이 반환 되었습니까? 객체 인스턴스를 만들지 않으면 상속이 어렵다는 것을 쉽게 알 수 있습니다. 상속이없는 추상 메소드는 본문이없는 메소드이므로 호출 할 수 없습니다.
또 다른 응답자 (McDowell)는 다형성이 객체 인스턴스에서만 작동한다고 말했다. 그것은 자격이 있어야합니다. 클래스를 "클래스"또는 "메타 클래스"유형의 인스턴스로 취급하는 언어가 있습니다. 이러한 언어는 인스턴스 및 클래스 (정적) 메서드 모두에 다형성을 지원합니다.
C #은 이전의 Java 및 C ++과 같은 언어가 아닙니다. static
키워드있어서 정적 바인딩보다는 동적 / 가상임을 표시하기 위해 명시 적으로 사용된다.
To add to the previous explanations, static method calls are bound to a specific method at compile-time, which rather rules out polymorphic behavior.
Here is a situation where there is definitely a need for inheritance for static fields and methods:
abstract class Animal
{
protected static string[] legs;
static Animal() {
legs=new string[0];
}
public static void printLegs()
{
foreach (string leg in legs) {
print(leg);
}
}
}
class Human: Animal
{
static Human() {
legs=new string[] {"left leg", "right leg"};
}
}
class Dog: Animal
{
static Dog() {
legs=new string[] {"left foreleg", "right foreleg", "left hindleg", "right hindleg"};
}
}
public static void main() {
Dog.printLegs();
Human.printLegs();
}
//what is the output?
//does each subclass get its own copy of the array "legs"?
We actually override static methods (in delphi), it's a bit ugly, but it works just fine for our needs.
We use it so the classes can have a list of their available objects without the class instance, for example, we have a method that looks like this:
class function AvailableObjects: string; override;
begin
Result := 'Object1, Object2';
end;
It's ugly but necessary, this way we can instantiate just what is needed, instead of having all the classes instantianted just to search for the available objects.
This was a simple example, but the application itself is a client-server application which has all the classes available in just one server, and multiple different clients which might not need everything the server has and will never need an object instance.
So this is much easier to maintain than having one different server application for each client.
Hope the example was clear.
The abstract methods are implicitly virtual. Abstract methods require an instance, but static methods do not have an instance. So, you can have a static method in an abstract class, it just cannot be static abstract (or abstract static).
참고URL : https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c
'IT' 카테고리의 다른 글
알파 테스터는 어디에서 Google Play Android 앱을 다운로드합니까? (0) | 2020.05.24 |
---|---|
파이썬 2는 문자열과 int를 어떻게 비교합니까? (0) | 2020.05.24 |
Google지도 확대 / 축소 컨트롤이 엉망입니다 (0) | 2020.05.24 |
캐스케이드 삭제 (0) | 2020.05.24 |
git remote update와 fetch의 차이점은 무엇입니까? (0) | 2020.05.24 |