Skip to content

int или typeof(int) - в чем разница?

edited March 2022 in Tutorials

Эта статья не про конкретный тип int, а вообще про все типы.

WriteLine(int); //System.Int32
WriteLine(typeof(int)); //System.Int32
WriteLine(int==typeof(int)); //True

Технически int - это постоянное значение типа object, но к типу которого прикреплена информация о том, что внутри тип. Специально вызовем ошибку:

int x=int; //Can't put value of type 'object/type:int' into variable of type 'int'.

А вот что с typeof(int), который является object-литералом:

int x=typeof(int); //Can't put value of type 'object' into variable of type 'int'.

Т.е. для интерпретатора typeof(int) - это обычный object.
На практике всегда можно писать просто int, а не typeof(int) потому, что короче.
Есть базовые функции (TInvoke, TGetValue, TGetElement, Eval), которые принимают аргумент-тип, и для них нужно писать без typeof.

object e=Expr(2+3); 
//int x=e.Eval(typeof(int)); // Function 'Eval(object, object)' not found at 'App'.
int x=e.Eval(int); //то же, что и Eval(e, int)
WriteLine(x); //5

В этом примере интерпретатор находит перегрузку Eval для int, чтобы возвращалось именно int-значение. Если написать с typeof, то он не сможет найти её, т.к. формально тип аргумента будет object.

Про свои типы

WriteLine(Foo); //App.Foo
WriteLine(typeof(Foo)); //App.Foo
WriteLine(typeof(Foo)==Foo); //True

class Foo{}

Foo - свой тип, но это не Type, а CustomType!

WriteLine(Foo->GetType()); //OverScript.CustomType
WriteLine(GetType(Foo)); //OverScript.CustomType

Некоторым функциям, возвращающим экземпляр своего типа, нужно на вход подавать аргумент-тип без typeof. Пример:

object obj=new Foo();
//Foo f=Foo\obj.As(typeof(Foo)); //так можно. As вернёт object.
//Foo f:=obj.As(typeof(Foo));  //и так можно. As вернёт object.
Foo f=obj.As(Foo);  //но лучше так. As вернёт Foo.
WriteLine(f); //Instance of Foo

class Foo{}

Ещё пример:

string js=ToJson(new Point(2, 3));
Point p=FromJson(js, Point); //если typeof(Point) написать, то FromJson вернёт object, который нужно приводить к Point 
WriteLine(p.X+"; "+p.Y); //2; 3

class Point{
    public int X, Y;
    New(int x, int y){
        X=x;
        Y=y;
    }
}

Если тип находится в переменной, то без приведения типа или оператора := не обойтись:

string js=ToJson(new Point(2, 3)); //можно написать: string js=new Point(2, 3).ToJson();
object type=Point; //тут без разницы Point или typeof(Point)
Point p=Point\FromJson(js, type); //или: Point p:=FromJson(js, type);
WriteLine(p.X+"; "+p.Y); //2; 3
...
Sign In or Register to comment.