케이스/스위치 및 gettype를 사용하여 객체를 결정합니다 [복제
-
22-08-2019 - |
문제
가능한 복제 :
C #- '유형을 켜기'하는 것보다 더 나은 대안이 있습니까?
당신이 원한다면 switch
한 유형의 물체 에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
코드 스 니펫
private int GetNodeType(NodeDTO node)
{
switch (node.GetType())
{
case typeof(CasusNodeDTO):
return 1;
case typeof(BucketNodeDTO):
return 3;
case typeof(BranchNodeDTO):
return 0;
case typeof(LeafNodeDTO):
return 2;
default:
return -1;
}
}
나는 이것이 그런 식으로 작동하지 않는다는 것을 알고 있지만, 당신이 이것을 어떻게 해결할 수 있는지 궁금했습니다. 이다 if/else
이 경우 적절한 진술?
아니면 스위치를 사용하고 추가합니까? .ToString()
유형에?
해결책
만약 내가 진짜 해야 했어 switch
물체의 유형에서 나는 사용할 것이다 .ToString()
. 그러나 나는 모든 비용으로 그것을 피할 것입니다. IDictionary<Type, int>
훨씬 더 잘할 것입니다. 방문객 과잉 일 수 있지만 그렇지 않으면 여전히 완벽한 솔루션입니다.
다른 팁
사용자 정의 유형을 켜고 싶을 때 문제를 직접 해결하지는 않지만 내장 유형을 켜고 자하는 다른 사람들의 이점을 위해 typecode 열거:
switch (Type.GetTypeCode(node.GetType()))
{
case TypeCode.Decimal:
// Handle Decimal
break;
case TypeCode.Int32:
// Handle Int32
break;
...
}
MSDN 블로그 게시물에서 많은 질문 : 유형을 켜십시오 이유에 대한 정보입니다 .그물 스위칭 유형을 제공하지 않습니다.
평소와 같이, 해결 방법은 항상 존재합니다.
이것은 내 것이 아니지만 불행히도 나는 소스를 잃었습니다. 유형을 켜는 것이 가능하지만 개인적으로는 매우 어색하다고 생각합니다 (사전 아이디어가 더 좋습니다).
public class Switch
{
public Switch(Object o)
{
Object = o;
}
public Object Object { get; private set; }
}
/// <summary>
/// Extensions, because otherwise casing fails on Switch==null
/// </summary>
public static class SwitchExtensions
{
public static Switch Case<T>(this Switch s, Action<T> a)
where T : class
{
return Case(s, o => true, a, false);
}
public static Switch Case<T>(this Switch s, Action<T> a,
bool fallThrough) where T : class
{
return Case(s, o => true, a, fallThrough);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a) where T : class
{
return Case(s, c, a, false);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> c, Action<T> a, bool fallThrough) where T : class
{
if (s == null)
{
return null;
}
T t = s.Object as T;
if (t != null)
{
if (c(t))
{
a(t);
return fallThrough ? s : null;
}
}
return s;
}
}
용법:
new Switch(foo)
.Case<Fizz>
(action => { doingSomething = FirstMethodCall(); })
.Case<Buzz>
(action => { return false; })
나는 단지 if 문을 사용합니다. 이 경우 :
Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ...
이 작업을 수행하는 다른 방법은 다음과 같습니다.
if (node is CasusNodeDTO)
{
}
else ...
첫 번째 예는 정확한 유형에 대해서만 참으로, 후자는 상속을 확인합니다.
나는 같은 문제에 직면 했고이 게시물을 발견했습니다. 이것이 유물 접근법의 의미입니다.
Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
{typeof(int),0},
{typeof(string),1},
{typeof(MyClass),2}
};
void Foo(object o)
{
switch (typeDict[o.GetType()])
{
case 0:
Print("I'm a number.");
break;
case 1:
Print("I'm a text.");
break;
case 2:
Print("I'm classy.");
break;
default:
break;
}
}
그렇다면 사전에서 사전에서 숫자를 조정하는 팬이라고 말할 수는 없습니다.
이것은 이상적이지만 사전 참조는 그것을 죽인다.
void FantasyFoo(object o)
{
switch (typeDict[o.GetType()])
{
case typeDict[typeof(int)]:
Print("I'm a number.");
break;
case typeDict[typeof(string)]:
Print("I'm a text.");
break;
case typeDict[typeof(MyClass)]:
Print("I'm classy.");
break;
default:
break;
}
}
간과 한 또 다른 구현이 있습니까?
당신은 이것을 할 수 있습니다 :
if (node is CasusNodeDTO)
{
...
}
else if (node is BucketNodeDTO)
{
...
}
...
그것은 더 우아 할 것이지만, 여기서 다른 답변만큼 효율적이지는 않을 것입니다.
당신은 이것을 할 수 있습니다 :
function void PrintType(Type t) {
var t = true;
new Dictionary<Type, Action>{
{typeof(bool), () => Console.WriteLine("bool")},
{typeof(int), () => Console.WriteLine("int")}
}[t.GetType()]();
}
명확하고 쉽습니다. 사전을 어딘가에 캐싱하는 것보다 조금 느립니다. 그러나 많은 코드의 경우 어쨌든 이것은 중요하지 않습니다 ..
한 가지 방법은 순수한 가상 getNodeType () 메소드를 추가하여 NODEDTO에이를 추가하여 자손에게 재정의하여 각 자손이 실제 유형을 반환하는 것입니다.
스위치 문에서 수행하는 일에 따라 정답은 다형성입니다. 인터페이스/기본 클래스에 가상 함수를 넣고 각 노드 유형에 대해 재정의하십시오.
나는 실제로 여기에서 답으로 주어진 접근법을 선호합니다.이것보다 '유형을 켜기'하는 것보다 더 나은 대안이 있습니까?
그러나 c#과 같은 객체 지향 언어로 유형 비교 메티드를 구현하지 않는다는 것이 좋은 주장이 있습니다. 상속을 사용하여 대체 확장 및 추가 필수 기능을 추가 할 수 있습니다.
이 점은 저자 블로그의 의견에서 다음과 같이 논의되었습니다.http://blogs.msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx#8553535
나는 이것이 비슷한 상황에서 내 접근 방식을 바꾸는 매우 흥미로운 점을 발견했으며 이것이 다른 사람들을 돕기를 희망합니다.
친절한 안부, 웨인