많은 사람들이 다음 코드를 사용하는 것을 보았습니다:
Type t = typeof(obj1);
if (t == typeof(int))
// Some code here
하지만 여러분도 이렇게 할 수 있다는 것을 알고 있습니다:
if (obj1.GetType() == typeof(int))
// Some code here
또는 이렇게 하세요:
if (obj1 is int)
// Some code here
개인적으로는 마지막이 가장 깔끔하다고 생각하는데 제가 놓친 부분이 있나요? 어느 것이 가장 좋은가요, 아니면 개인적인 취향인가요?
모두 다르다.
< h3> Example< /h3>;;;
class Animal { }
class Dog : Animal { }
void PrintTypes(Animal a) {
Console.WriteLine(a.GetType() == typeof(Animal)); // false
Console.WriteLine(a is Animal); // true
Console.WriteLine(a.GetType() == typeof(Dog)); // true
Console.WriteLine(a is Dog); // true
}
Dog spot = new Dog();
PrintTypes(spot);
< hr>;
>. (T) '' 메리 페로프 어때? 또한 해결되었으므로 는 컴파일 타임에?
예. T 는 항상 어떤 유형의 표현식에서는 있다. 단, 기본적으로 일반 방법은 여러 가지 방법을 통해 적절한 유형을 것과 마찬가지입니다. 예:
string Foo<T>(T parameter) { return typeof(T).Name; }
Animal probably_a_dog = new Dog();
Dog definitely_a_dog = new Dog();
Foo(probably_a_dog); // this calls Foo<Animal> and returns "Animal"
Foo<Animal>(probably_a_dog); // this is exactly the same as above
Foo<Dog>(probably_a_dog); // !!! This will not compile. The parameter expects a Dog, you cannot pass in an Animal.
Foo(definitely_a_dog); // this calls Foo<Dog> and returns "Dog"
Foo<Dog>(definitely_a_dog); // this is exactly the same as above.
Foo<Animal>(definitely_a_dog); // this calls Foo<Animal> and returns "Animal".
Foo((Animal)definitely_a_dog); // this does the same as above, returns "Animal"
컴파일 시에 타입을 가져오려면 typeof
를 사용합니다. 실행 시 실행 시*에 타입을 가져오고 싶을 때는 GetType
을 사용합니다. is`는 형변환을 수행하므로 사용할 경우가 거의 없으며, 대부분의 경우 결국 변수를 형변환하게 됩니다.
여러분이 고려하지 않은 네 번째 옵션이 있습니다(특히 찾은 유형으로 객체를 캐스팅하려는 경우); 그것은 as
를 사용하는 것입니다.
Foo foo = obj as Foo;
if (foo != null)
// your code here
이 방법은 하나의 형변환만 사용하는 반면 이 방법은 하나의 형변환만 사용합니다:
if (obj is Foo)
Foo foo = (Foo)obj;
는 둘이 필요합니다.
1.
Type t = typeof(obj1);
if (t == typeof(int))
이건 불법 메리 페로프 때문에 때만 아닌 추상형데이터타입 대한 변수에 의존한다. 내가 solaris. obj1 은 변수. 그래서, 이런 식으로 메리 페로프 는 컴파일 타임에 업무를 대신 정적 및 높여줍니까 런타임용으로 개발하십시오.
2.
if (obj1.GetType() == typeof(int))
이 경우 int, int 유형의 obj1 것은 확실히 obj1 될 경우 if 에서 파생시킵니다 찼음을 거짓값.
3.
if (obj1 is int)
이것은 int, int 의 경우, 아니면 진정한 obj1 백업이었습니다 파생시킵니다 클래스 불렀으매 구축, 아니면 인터페이스입니다 호출됨 int.
Type t = typeof(obj1);
if (t == typeof(int))
// Some code here
이것은 오류가 발생했습니다. C # 에서 수행되는 연산자입니다 수만 시행하십시오 유형 이름, 객체가 아닌.
if (obj1.GetType() == typeof(int))
// Some code here
이렇게 하면 원하는 대로 일을 않을 수도 있을 것으로 기대하고 있다. # 39 로, ve, it& you& 값에 대한 유형, 이 슬라이드에서는 # 39 에 사용할 수 있으나,) 는 동일한 문자 참조 유형을 것이다 유형, 안 되면 무언가 복귀하십시오 상속 계층 구조에서. 예를 들면 다음과 같습니다.
class Animal{}
class Dog : Animal{}
static void Foo(){
object o = new Dog();
if(o.GetType() == typeof(Animal))
Console.WriteLine("o is an animal");
Console.WriteLine("o is something else");
}
이는 ',', 'o 는 인쇄하십시오 " 뭔가 else" 때문에' 동물 'o' 는 '개이라 아닌 유형의'. 그러나 이 작품을 만들 수 있습니다 '방법' 을 사용할 경우 이사시냐블레프롬 '유형' 클래스.
if(typeof(Animal).IsAssignableFrom(o.GetType())) // note use of tested type
Console.WriteLine("o is an animal");
이 기법은 찻입 여전히 심각한 문제가 될 수 있지만. 이 경우, a call to throw 게티페 () '은' nulll 가변입니다 누얼레페렌스엑스티온. 그래서 이를 제대로 작동하려면 you& # 39; d do.
if(o != null && typeof(Animal).IsAssignableFrom(o.GetType()))
Console.WriteLine("o is an animal");
이와 함께 '는' 키워드 중 avamer 비헤이비어를 있습니다. 따라서, 이 경우, 이는 '는' 키워드를 비헤이비어를 운영까지도 콩지름에 가독성을 높이고 보다 더 효율적이다.
if(o is Animal)
Console.WriteLine("o is an animal");
하지만, 대부분의 경우 '는' 키워드 그래도말야 isn& # 39, t, s # 39 it& 너희는너희가 진정으로 원하는 만큼 알고 있기 때문에, 보통 그냥 객체가 특정 유형의. 일반적으로, 실제로 사용할 수 있는 운영까지도 로케이터로 인스턴스입니다 해당 유형에 필요한 캐스팅 너무. 그래서 다음과 같은 코드를 먹어서나 교도관님도요 찾아볼 수 있습니다.
if(o is Animal)
((Animal)o).Speak();
그러나 CLR object& 확인 할 수 있는 # 39 의 유형을 최대 2 배. 또 한 번 확인할 수 있는 'o' 는 '는' 연산자입니다 만족시킬 경우, 그 '동물', 다시 검증하십시오 확인란 거냐 "라고 언급했다.
Animal a = o as Animal;
if(a != null)
a.Speak();
하지만 주의해야 합니다. 많은 사람들이 함께 트랩할 빠지는 '도'. # 39 doesn& 때문에, t, 일부 사람들이 아니라, safe" " 예외가 발생합니다. 이를 사용하여, 캐스팅, 그들은 단독으로 기피 일반 방송. 이로 인해 오류뿐만 다음과 같습니다.
(o as Animal).Speak();
이 경우 회사는 확실히요 'o' 가 될 것으로 보고 항상 '동물', 그리고 그들의 가정 정확한지 deltamove 설명하였노라 작동합니다. 그들이 잘못된 종료 후, re 신앙이니라 they& # 39 이것은 누얼레페렌스엑스티온 '가'. 함께 한 '대신' 일반 캐스트 (cast), 그들은 틀림없이 이 문제를 제대로 된 베르발드카스티스세페시옹 식별됩니다 더 있을 것이라고 말했다.
가끔 이 버그는 찾기 힘들 수 있습니다.
class Foo{
readonly Animal animal;
public Foo(object o){
animal = o as Animal;
}
public void Interact(){
animal.Speak();
}
}
이것은 또 다른 개발자가 되기 위해 '동물' 는 'o' 확실히요 검색되어야 사례가 있지만, 이 때마다 isn& # 39 에 있는 '으로, t 명백하네 구성자를' 캐스트 사용됩니다. # 39 에 도달할 때까지 ',' s not 명백하네 it& 있는 '동물' 이 방법을 적극 상호 작용하는 것으로 필드는 배정됩니다. 이 경우 들어보겠소 아니라 끝날 때까지 함께 잘못된 것이며, 잠재적으로 때보다 훨씬 나중에 t # 39 isn& idfsysobject. 있지만 실제 오류가 발생했습니다.
요약:
경우에만 사용 여부를 알아야 할 몇 가지 유형, 객체가 '는'.
할 경우 특정 유형의 인스턴스를 로케이터로 처리하는 확장하지만 don& # 39, 확신할 수 있을지 알 수 없다 '를 사용하여 확인할지 객체에는 적립율은 해당 유형의' 와 'null'.
로케이터로 인스턴스입니다 처리하는 할 경우 특정 유형 및 객체인지 있어야 사용하여 해당 유형의 일반 출연자.
난 이미 속성 비교할 수 있도록 한 '유형' 과 '는' (like '는' my_type _basetypetolookfor) 사용할 수 없습니다, 하지만 난 이 사용할 수 있습니다.
base_type.IsInstanceOfType(derived_object);
base_type.IsAssignableFrom(derived_type);
derived_type.IsSubClassOf(base_type);
'리턴' 진정한 '' '와' 이사시냐블레프롬 이신스턴스로프티파 것을 볼 수 있는 반환되므로 아서브클라소프 비교할 때 같은 유형은 '거짓'. 여기서 '와' 아서브클라소프 인터페이스와도 작동하지 않는 다른 두 개의 책임질래. (참조 이 질문과 대답을).
public class Animal {}
public interface ITrainable {}
public class Dog : Animal, ITrainable{}
Animal dog = new Dog();
typeof(Animal).IsInstanceOfType(dog); // true
typeof(Dog).IsInstanceOfType(dog); // true
typeof(ITrainable).IsInstanceOfType(dog); // true
typeof(Animal).IsAssignableFrom(dog.GetType()); // true
typeof(Dog).IsAssignableFrom(dog.GetType()); // true
typeof(ITrainable).IsAssignableFrom(dog.GetType()); // true
dog.GetType().IsSubclassOf(typeof(Animal)); // true
dog.GetType().IsSubclassOf(typeof(Dog)); // false
dog.GetType().IsSubclassOf(typeof(ITrainable)); // false
if (obj1 is int integerValue)
{
integerValue++;
}
하지만 지금 이 예쁜 디자인 한 이 같은 캐스팅 실망 여러 개 있을 때 가능한 유형은상위 자위행위를 시화호로 들어오는 빛을 발한다. 이전 두 차례 피할 길은 아래 있다 "고 말했다.
Button button = obj1 as Button;
if (button != null)
{
// do stuff...
return;
}
TextBox text = obj1 as TextBox;
if (text != null)
{
// do stuff...
return;
}
Label label = obj1 as Label;
if (label != null)
{
// do stuff...
return;
}
// ... and so on
이 코드는 업으로 최대한 중복을 방지할 뿐만 아니라 방송 축소 같은 객체에는 항상 나를 괴롭혔다. 위의 아주 잘 압축됨 함께 패턴 매칭 다음과 같습니다.
switch (obj1)
{
case Button button:
// do stuff...
break;
case TextBox text:
// do stuff...
break;
case Label label:
// do stuff...
break;
// and so on...
}
편집: # 39 의 스위치를 사용할 수 있는 새로운 방법을 따라 Palec& 업데이트되도록 더 이상 언급은 하지 않았다.
내가 < 포지셔닝하십시오 b> is< /b>;;;
즉,,, 사용하는 경우, re < you& # 39 b> is< /b> you& < em> not< /em>;;; re # 39 것으로 보인다. 상속을 사용하면 비판을 받아왔다.
Solaris. 사람이. 엔티티입니다 있는 및 동물: 엔티티입니다. 급지가 는 가상 메서드를 (company. 닐 행복하게 만들 수 있습니다)
<! - 언어: c # - >.
class Person
{
// A Person should be able to Feed
// another Entity, but they way he feeds
// each is different
public override void Feed( Entity e )
{
if( e is Person )
{
// feed me
}
else if( e is Animal )
{
// ruff
}
}
}
대답하도다
<! - 언어: c # - >.
class Person
{
public override void Feed( Person p )
{
// feed the person
}
public override void Feed( Animal a )
{
// feed the animal
}
}
System.Type type = typeof(int);
Example:
public class ExampleClass
{
public int sampleMember;
public void SampleMethod() {}
static void Main()
{
Type t = typeof(ExampleClass);
// Alternatively, you could use
// ExampleClass obj = new ExampleClass();
// Type t = obj.GetType();
Console.WriteLine("Methods:");
System.Reflection.MethodInfo[] methodInfo = t.GetMethods();
foreach (System.Reflection.MethodInfo mInfo in methodInfo)
Console.WriteLine(mInfo.ToString());
Console.WriteLine("Members:");
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
Console.WriteLine(mInfo.ToString());
}
}
/*
Output:
Methods:
Void SampleMethod()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
Members:
Void SampleMethod()
System.String ToString()
Boolean Equals(System.Object)
Int32 GetHashCode()
System.Type GetType()
Void .ctor()
Int32 sampleMember
*/
class GetTypeTest
{
static void Main()
{
int radius = 3;
Console.WriteLine("Area = {0}", radius * radius * Math.PI);
Console.WriteLine("The type is {0}",
(radius * radius * Math.PI).GetType()
);
}
}
/*
Output:
Area = 28.2743338823081
The type is System.Double
*/
성능 테스트 메리 페로프 () 와 게티페 ():
using System;
namespace ConsoleApplication1
{
class Program
{
enum TestEnum { E1, E2, E3 }
static void Main(string[] args)
{
{
var start = DateTime.UtcNow;
for (var i = 0; i < 1000000000; i++)
Test1(TestEnum.E2);
Console.WriteLine(DateTime.UtcNow - start);
}
{
var start = DateTime.UtcNow;
for (var i = 0; i < 1000000000; i++)
Test2(TestEnum.E2);
Console.WriteLine(DateTime.UtcNow - start);
}
Console.ReadLine();
}
static Type Test1<T>(T value) => typeof(T);
static Type Test2(object value) => value.GetType();
}
}
디버그 모드로 결과:
00:00:08.4096636
00:00:10.8570657
결과 릴리스에는 모드:
00:00:02.3799048
00:00:07.1797128