문제

가능한 복제 :
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

나는 이것이 비슷한 상황에서 내 접근 방식을 바꾸는 매우 흥미로운 점을 발견했으며 이것이 다른 사람들을 돕기를 희망합니다.

친절한 안부, 웨인

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top