문제
내 안에 다른 과부하 메소드를 부르는 방법이 있습니다. 외부 메소드의 매개 변수가 내부로 전달되기 때문에 하나의 외부 방법 만 쓰려고합니다. 이것을 할 방법이 있습니까?
제네릭을 사용하려고 시도했지만 이것에 대해 충분히 알지 못하므로 작동하지 않습니다.
public void OuterMethod<T>(T parameter)
{
InnerMethod(parameter); // InnerMethod accepts an int or a string
}
나는 이것을 할 수 있다는 것을 알고있다 :
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter);
}
그러나 코드를 복사/붙여 넣기 대신 올바른 방법으로 이것을 할 것입니다. 이것을 달성하는 가장 좋은 방법은 무엇입니까?
해결책
C ++에서는이 작업을 수행 할 수 있지만 C#에서는 할 수 없습니다 (내부 방법이 과부하 대신 일반적인 방법이 아니라면).
또는 (답을 위해 '아니오'를받지 않으면) 예를 들어 ...처럼 런타임 스위치를 켜면 ...
public void OuterMethod(object parameter)
{
if (parameter is int)
InnerMethod((int)parameter);
else if (parameter is string)
InnerMethod((string)parameter);
else
throw new SomeKindOfException();
}
... 분명히 이것은 컴파일 타임 체크가 아니라 런타임입니다.
그러나 코드를 복사/붙여 넣기 대신 올바른 방법으로 이것을 할 것입니다.
또한 소프트웨어를 작성하여 OUTER 방법 (예 : System.Codedom 클래스)을 손으로 작성하는 대신 작성할 수 있지만 이는 가치보다 더 어려울 수 있습니다.
다른 팁
다른 사람들이 말했듯이, 당신은 실제로 당신이하려는 일을 할 수 없으며 질문에 언급 한 선택이 가장 좋은 방법입니다.
일반을 사용하는 경우 실제로 값을 변환해야합니다. 그렇지 않으면 Chrisw가 제안한대로 객체를 수락하여 다운 캐스트 할 수 있습니다.
public void OuterMethod<T>(T parameter)
{
T temp = parameter;
if (temp is string )
InnerMethod(Convert.ToString(temp));
if (temp is int)
InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
}
다음은 제네릭의 개요에 대한 링크입니다. http://msdn.microsoft.com/en-us/library/ms172193.aspx
설명에서 이것은 과도한 최적화처럼 보입니다.
어때요 :
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter**.ToString()**);
}
당신은 a를 사용할 수 있습니다 dynamic
런타임까지 과부하 해상도를 연기하려면 입력하십시오.
public void OuterMethod(dynamic parameter)
{
InnerMethod(parameter);
}
public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }
경고 유형 동적 표현식은 컴파일러에 의해 해결되거나 유형을 확인하지 않습니다. 그리고 성과 페널티도있을 수 있습니다.
outermethod가 항상 내부 메드를 호출하고 Innermethod가 int 또는 string 만 수락 한 다음 outermethodu003CT> 말이되지 않습니다.
만약 뿐 차이점은 내부 메트 (int)를 호출하고 다른 하나는 내부 방법 (문자열)을 호출한다는 것입니다.
public void OuterMethod(string parameter)
{
InnerMethodA(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethodA(parameter);
}
private void InnerMethodA(object parameter)
{
// Whatever other implementation stuff goes here
if (parameter is string)
{
InnerMethodB((string) parameter);
}
else if (parameter is int)
{
InnerMethodB((string) parameter);
}
else
{
throw new ArgumentException(...);
}
}
private void InnerMethodB(string parameter)
{
// ...
}
private void InnerMethodB(int parameter)
{
// ...
}
좋아, 비슷한 상황이 있고 비즈니스 로직에서 액세스 제어 방법입니다.
내 영구 레이어 객체에 적용 할 수있는 저장 함수가 있습니다.
그래서 이렇게 보입니다
public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
if(CanWrite(user, entity))
{
entity.save();
}
else
{
throw new Exception("Cannot Save");
}
}
액세스 컨트롤 측면에서 특정 엔티티에 대한 사용자 정의 코드가 있는데 다음을 작성했습니다. 시스템을 사용하여 질문에 더 적합한 방법을 찾습니다. "이 엔티티 가이 사용자가 작성할 수 있습니까?"
public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
{
int? clubId = null;
MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
if(methodInfo != null)
{
return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
}
else
{
//generic answer
}
return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
}
이제 메소드를 추가하거나 제거 할 때마다 메소드를 한 곳에서 추가하거나 제거하면됩니다.