유형 C #에서 케이스 전환
안녕하세요, 클래스 유형에 대해 큰 if / else가 있다고 가정합니다. 스위치 케이스로 할 수있는 방법이 있습니까?
예 :
function test(object obj)
{
if(obj is WebControl)
{
}else if(obj is TextBox)
{
}
else if(obj is ComboBox)
{
}
등 ...
나는 다음과 같은 것을 만들고 싶다.
switch(obj)
{
case is TextBox:
break;
case is ComboBox:
break;
}
}
아니.
http://blogs.msdn.com/b/peterhal/archive/2005/07/05/435760.aspx
우리는 C # 언어에 대한 추가에 대한 많은 요청을 받고 있으며 오늘은 더 일반적인 것 중 하나 인 스위치 켜기 유형에 대해 이야기 할 것입니다. Switch on type은 매우 유용하고 직관적 인 기능처럼 보입니다. 값이 아닌 표현식의 유형을 전환하는 스위치와 같은 구조를 추가합니다. 다음과 같이 보일 수 있습니다.
switch typeof(e) {
case int: ... break;
case string: ... break;
case double: ... break;
default: ... break;
}
이러한 종류의 문은 분리 된 유형 계층 구조 또는 소유하지 않은 유형을 포함하는 유형 계층 구조를 통한 디스패치와 같은 가상 메서드를 추가하는 데 매우 유용합니다. 이와 같은 예를 보면 해당 기능이 간단하고 유용하다고 쉽게 결론을 내릴 수 있습니다. "왜 # * & % $ 게으른 C # 언어 디자이너가 내 삶을 더 쉽게 만들고이 간단하고 시간을 절약 할 수있는 언어 기능을 추가하지 않겠습니까?"라고 생각할 수도 있습니다.
불행히도 많은 '간단한'언어 기능과 마찬가지로 유형 스위치는 처음 나타나는 것처럼 간단하지 않습니다. 문제는 다음과 같이 더 중요하고 덜 중요한 것을 볼 때 시작됩니다.
class C {}
interface I {}
class D : C, I {}
switch typeof(e) {
case C: … break;
case I: … break;
default: … break;
}
링크 : https://blogs.msdn.microsoft.com/peterhal/2005/07/05/many-questions-switch-on-type/
C # 7 업데이트
예 : 소스
switch(shape)
{
case Circle c:
WriteLine($"circle with radius {c.Radius}");
break;
case Rectangle s when (s.Length == s.Height):
WriteLine($"{s.Length} x {s.Height} square");
break;
case Rectangle r:
WriteLine($"{r.Length} x {r.Height} rectangle");
break;
default:
WriteLine("<unknown shape>");
break;
case null:
throw new ArgumentNullException(nameof(shape));
}
다음 코드는 실제 유형 (예 :에서 반환 된 것 GetType()
) 만 보는 유형 스위치를 예상하는 것처럼 다소 작동합니다 .
public static void TestTypeSwitch()
{
var ts = new TypeSwitch()
.Case((int x) => Console.WriteLine("int"))
.Case((bool x) => Console.WriteLine("bool"))
.Case((string x) => Console.WriteLine("string"));
ts.Switch(42);
ts.Switch(false);
ts.Switch("hello");
}
작동하는 데 필요한 기계가 있습니다.
public class TypeSwitch
{
Dictionary<Type, Action<object>> matches = new Dictionary<Type, Action<object>>();
public TypeSwitch Case<T>(Action<T> action) { matches.Add(typeof(T), (x) => action((T)x)); return this; }
public void Switch(object x) { matches[x.GetType()](x); }
}
예, 이름을 켤 수 있습니다 ...
switch (obj.GetType().Name)
{
case "TextBox":...
}
다음은 유형을 전환 할 수 있도록 OP의 요구 사항에 맞출 수있는 사실로 유지되는 옵션입니다. 충분히 세게 가늘게 뜨면 실제 switch 문처럼 보입니다.
호출 코드는 다음과 같습니다.
var @switch = this.Switch(new []
{
this.Case<WebControl>(x => { /* WebControl code here */ }),
this.Case<TextBox>(x => { /* TextBox code here */ }),
this.Case<ComboBox>(x => { /* ComboBox code here */ }),
});
@switch(obj);
위 x
의 각 람다는 강력한 형식입니다. 캐스팅이 필요하지 않습니다.
이 마법이 작동하도록하려면 다음 두 가지 방법이 필요합니다.
private Action<object> Switch(params Func<object, Action>[] tests)
{
return o =>
{
var @case = tests
.Select(f => f(o))
.FirstOrDefault(a => a != null);
if (@case != null)
{
@case();
}
};
}
private Func<object, Action> Case<T>(Action<T> action)
{
return o => o is T ? (Action)(() => action((T)o)) : (Action)null;
}
거의 눈물을 흘리 죠?
그럼에도 불구하고 작동합니다. 즐겨.
가장 간단한 방법은 역학을 사용하는 것입니다. 즉, Yuval Peled 답변과 같은 간단한 방법을 정의합니다.
void Test(WebControl c)
{
...
}
void Test(ComboBox c)
{
...
}
Then you cannot call directly Test(obj), because overload resolution is done at compile time. You have to assign your object to a dynamic and then call the Test method:
dynamic dynObj = obj;
Test(dynObj);
참고URL : https://stackoverflow.com/questions/7252186/switch-case-on-type-c-sharp
'programing tip' 카테고리의 다른 글
Windows XP에서 MySQL 명령 줄 클라이언트를 통해 열린 MySQL 화면을 지우는 방법 (0) | 2020.12.10 |
---|---|
비교 기능과 함께 JavaScript에서 정렬 기능이 작동하는 방법 (0) | 2020.12.10 |
Java에서 ResultSet이 리턴 한 행 수 가져 오기 (0) | 2020.12.10 |
Mac OS X에 pdftk를 설치하는 방법 (0) | 2020.12.10 |
암호 재설정 토큰 생성이 Azure 웹 사이트에서 작동하지 않습니다. (0) | 2020.12.10 |