일반 메서드가있는 인터페이스가 필요합니다. 그러나 해당 인터페이스의 각 구현은 해당 유형을 알고 있습니다.
class Program
{
static void Main(string[] args)
{
var specificContext = new SpecificContext();
var res = new SrvThatCantBeGeneric().GetValueFromSpecificContext(specificContext);
Console.WriteLine(res);
}
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)
{
return specificContext.MyProperty; // <-- this is where it breaks
}
}
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>( T specificContext);
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
어떤 이유로 내가 위의 방식으로 할 때 작동하지 않고 다음과 같이 말합니다.
'SpecificContext'에 'MyProperty'에 대한 정의가 포함되어 있지 않으며 'SpecificContext'유형의 첫 번째 인수를 허용하는 액세스 가능한 확장 메서드 'MyProperty'를 찾을 수 없습니다 (using 지시문 또는 어셈블리 참조가 누락 되었습니까?).
왜 이런 일이 발생하고 어떻게 해결합니까?
다음과 같이 제네릭 유형의 정의를 이동하여 수정할 수 있습니다.
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric<SpecificContext>
{
public int GetValueFromSpecificContext(SpecificContext specificContext)
{
return specificContext.MyProperty; // <-- this is where it breaks
}
}
public interface ISrvThatCantBeGeneric<T>
{
int GetValueFromSpecificContext( T specificContext);
}
그러나 이것은 코드의 다른 부분에서 중단되며 진행되지 않습니다.
편집 : 내 코드 단순화
작성하여 :
public int GetValueFromSpecificContext<SpecificContext>(SpecificContext specificContext)
범위를 "재정의"하고 여기 SpecificContext
에이 이름을 가진 클래스를 마스킹하는 일반 유형 매개 변수가 있으므로 다음과 동일합니다.
public int GetValueFromSpecificContext<T>(T specificContext)
아마도 다음과 같이 작성하고 싶을 것입니다.
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext;
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<T>(T specificContext) where T : SpecificContext
{
return specificContext.MyProperty;
}
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
public class SpecificContextChild : SpecificContext
{
public SpecificContextChild()
{
MyProperty = 10;
}
}
테스트
var server = new SrvThatCantBeGeneric();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));
산출
10
또한 인터페이스와 클래스를 메서드 자체가 아닌 제네릭으로 승격 할 수 있습니다.
관련이있는 경우 :
public interface ISrvThatCantBeGeneric<T> where T : SpecificContext
{
int GetValueFromSpecificContext(T specificContext);
}
public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : SpecificContext
{
public int GetValueFromSpecificContext(T specificContext)
{
return specificContext.MyProperty;
}
}
public class SpecificContext
{
public int MyProperty { get; set; } = 42;
}
public class SpecificContextChild : SpecificContext
{
public SpecificContextChild()
{
MyProperty = 10;
}
}
var server = new SrvThatCantBeGeneric<SpecificContextChild>();
var context = new SpecificContextChild();
Console.WriteLine(server.GetValueFromSpecificContext(context));
또한 선호하거나 필요한 경우 기본 클래스 대신 인터페이스를 사용할 수 있습니다.
public interface IContext
{
int MyProperty { get; set; }
}
비 일반 클래스 버전 :
public interface ISrvThatCantBeGeneric
{
int GetValueFromSpecificContext<T>(T specificContext) where T : IContext;
}
public class SrvThatCantBeGeneric : ISrvThatCantBeGeneric
{
public int GetValueFromSpecificContext<T>(T specificContext) where T : IContext
{
return specificContext.MyProperty;
}
}
public class SpecificContext : IContext
{
public int MyProperty { get; set; } = 42;
}
일반 클래스 버전 :
public interface ISrvThatCantBeGeneric<T> where T : IContext
{
int GetValueFromSpecificContext(T specificContext);
}
public class SrvThatCantBeGeneric<T> : ISrvThatCantBeGeneric<T> where T : IContext
{
public int GetValueFromSpecificContext(T specificContext)
{
return specificContext.MyProperty;
}
}
public class SpecificContext : IContext
{
public int MyProperty { get; set; } = 42;
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다