제네릭 형식 매개 변수에 대한 정적 메서드 호출
나는 이와 같은 일을하고 싶었지만 C #에서는 불법으로 시청합니다.
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
타임 오류가 발생합니다. " 'T'는 '유효한 라우팅 변수'입니다."
제네릭 형식 매개 변수가 주어지면 제네릭 클래스에서 정적 메서드를 어떻게 호출 할 수 있습니까? 제약 조건이 주어지면 정적 메서드를 사용할 수 있습니다.
이 경우에 제약 된 형식에 대해 직접 정적 메서드를 호출해야합니다. C # (및 CLR)은 가상 정적 메서드를 지원하지 않습니다. 그래서 :
T.StaticMethodOnSomeBaseClassThatReturnsCollection
... 다음과 다를 수 없습니다.
SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection
제네릭 유형 매개 변수를 거치는 것이없이 간접적이라고 지원하지 않습니다.
이전 답변에 대해 설명하기 위해 여기에서 원하는 것에 대해 더 가깝다고 생각합니다. 나는 당신이 할 일을해야하거나 말아야하는 이유를 1001 개 줄 수있다. 나는 단지 당신의 질문에 대답 할 것입니다. 제네릭 매개 변수의 유형에 대해 GetMethod 메소드를 호출하고 거기에서 가야를 생각합니다. 예를 들어, 함수의 경우 :
public void doSomething<T>() where T : someParent
{
List<T> items=(List<T>)typeof(T).GetMethod("fetchAll").Invoke(null,new object[]{});
//do something with items
}
여기서 T는 메소드 메소드 fetchAll ()이있는 모든 클래스입니다.
예, 나는 이것이 끔찍하게 느리고 someParent가 모든 하위 클래스가 fetchAll을 구현하도록 강요하지 충돌 할 수 있음을 알고 질문에 대답합니다.
호출하는 유일한 방법은 리플렉션을 통하는 것입니다. 그러나 인터페이스에 해당 기능을 래핑하고 인스턴스 기반 IoC / 팩토리 / 등 패턴을 사용하는 것이 가능할 것입니다.
C #에 "가상 정적 방법"이 사실을 해결하기 위해 제네릭을 사용하는 것입니다.
불행히도 작동하지 않을 것입니다.
지금은 할 수 없습니다. 당신은 컴파일러에게 T가 그 방법을 가지고있는 것을 알려주는 방법이 필요합니다. 현재로서는 그렇게 할 방법이 없습니다. (많은 사람들이 일반 제약 조건에 수있는 것을 확장 할 수 있습니다.)
여기에 작동하는 예제를 게시하면 해결 방법입니다.
public interface eInterface {
void MethodOnSomeBaseClassThatReturnsCollection();
}
public T:SomeBaseClass, eInterface {
public void MethodOnSomeBaseClassThatReturnsCollection()
{ StaticMethodOnSomeBaseClassThatReturnsCollection() }
}
public Collection MethodThatFetchesSomething<T>() where T : SomeBaseClass, eInterface
{
return ((eInterface)(new T()).StaticMethodOnSomeBaseClassThatReturnsCollection();
}
나는 상황에 따라 해결할 대리인이 그것을 버리고 싶었습니다.
어떤 종류의 팩토리 또는 초기화 메서드로 정적 메서드를 호출해야하는 경우 대리자를 선언하고 정적 메서드를 관련 제네릭 팩토리 또는이 "이 정적 메서드가있는 제네릭 클래스"가 필요한 모든 것에 전달할 수 있습니다.
예를 들면 :
class Factory<TProduct> where TProduct : new()
{
public delegate void ProductInitializationMethod(TProduct newProduct);
private ProductInitializationMethod m_ProductInitializationMethod;
public Factory(ProductInitializationMethod p_ProductInitializationMethod)
{
m_ProductInitializationMethod = p_ProductInitializationMethod;
}
public TProduct CreateProduct()
{
var prod = new TProduct();
m_ProductInitializationMethod(prod);
return prod;
}
}
class ProductA
{
public static void InitializeProduct(ProductA newProduct)
{
// .. Do something with a new ProductA
}
}
class ProductB
{
public static void InitializeProduct(ProductB newProduct)
{
// .. Do something with a new ProductA
}
}
class GenericAndDelegateTest
{
public static void Main()
{
var factoryA = new Factory<ProductA>(ProductA.InitializeProduct);
var factoryB = new Factory<ProductB>(ProductB.InitializeProduct);
ProductA prodA = factoryA.CreateProduct();
ProductB prodB = factoryB.CreateProduct();
}
}
안타깝게도 클래스에 올바른 메서드가 있다고 강제 할 수는 없지만 결과 팩토리 메서드가 예상하는 모든 것을 포함하도록 (즉, 정확히 올바른 서명이있는 초기화 메서드) 적어도 컴파일 타임에 적용 할 수 있습니다. 이것은 런타임 리플렉션 예외보다 낫습니다.
이 접근법은 또한 몇 가지 이점이 있습니다. 즉, init 메소드를 재사용하고 인스턴스 메소드가 될 수 있습니다.
여기에 설명 된대로 리플렉션을 사용하여이 작업을 수행 할 수 있어야합니다.
참고 URL : https://stackoverflow.com/questions/196661/calling-a-static-method-on-a-generic-type-parameter
'IT' 카테고리의 다른 글
npm 경고 ……의 피어가 필요하지만 설치되어 있지 않습니다. (0) | 2020.08.22 |
---|---|
기존 Visual Studio 프로젝트에서 Visual Studio 프로젝트 유형을 어떻게 지정합니까? (0) | 2020.08.22 |
서비스 버스 란 무엇이며 언제 필요하십니까? (0) | 2020.08.22 |
Mocha로 JavaScript 테스트 -console.log를 사용하여 테스트를 디버깅해야합니까? (0) | 2020.08.22 |
MANIFEST.in이 필요하며 그 안에 무엇이 거기에 있습니까? (0) | 2020.08.22 |