Перейти к содержимому

Фотография

[DelphiScript] Использование nil


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 9

#1 Al_chimic

Al_chimic

    Новый участник

  • Members
  • Pip
  • 16 сообщений

Отправлено 15 декабря 2010 - 06:40

Доброго времени суток.

Не совсем понятно, почему nil в TestComplete трактуется как Integer (со значением 0, т.е. инициализация переменной типа int по умолчанию). Более того, если объекту типа OleVariant присвоить значение nil, то объект приводится к типу Integer.
Вот пример. Можно поставить точку останова на Log.Message и посмотреть значение и тип obj и nil в WatchList.

Procedure test;
var 
 obj : OleVariant;
begin
 obj : = nil;
 Log.Message(obj);
end;

В связи с этим вопрос, как обнулять ссылку на объект или, к примеру, вызывать методы из .Net Assembly c передачей в параметрах nil - в обоих случаях проводится неявное приведение к типу int со значением 0.

Также нельзя проверить на null:
Procedure test321;
var 
 obj : OleVariant;
begin
 obj : = Sys.Process('TestProcess').AppDomain('TestProcess.exe').dotNET.TestNamespace.TestClass.SomeMethod;
 if obj = nil then // Проверка не проходит в случае, если метод возвращает null!  
    Log.Message('Method returns null');
end;

  • 0

#2 Zenturio

Zenturio

    Опытный участник

  • Members
  • PipPipPipPip
  • 386 сообщений
  • ФИО:Дмитрий
  • Город:Смоленск - Москва


Отправлено 15 декабря 2010 - 08:12

Доброго времени суток.

Не совсем понятно, почему nil в TestComplete трактуется как Integer (со значением 0, т.е. инициализация переменной типа int по умолчанию). Более того, если объекту типа OleVariant присвоить значение nil, то объект приводится к типу Integer.
Вот пример. Можно поставить точку останова на Log.Message и посмотреть значение и тип obj и nil в WatchList.

Procedure test;
var 
 obj : OleVariant;
begin
 obj : = nil;
 Log.Message(obj);
end;

В связи с этим вопрос, как обнулять ссылку на объект или, к примеру, вызывать методы из .Net Assembly c передачей в параметрах nil - в обоих случаях проводится неявное приведение к типу int со значением 0.

Также нельзя проверить на null:
Procedure test321;
var 
 obj : OleVariant;
begin
 obj : = Sys.Process('TestProcess').AppDomain('TestProcess.exe').dotNET.TestNamespace.TestClass.SomeMethod;
 if obj = nil then // Проверка не проходит в случае, если метод возвращает null!  
    Log.Message('Method returns null');
end;


Я правильно понимаю, вы пытаетесь сравнить с Nil метод.
А сравнивать нужно объект - т.е в вашем случае метод должен возвращать объект.
Методы могут возвращать значения, отличные от Nil, если они объявлены как статические.
Как объявлен ваш метод?
  • 0

#3 Al_chimic

Al_chimic

    Новый участник

  • Members
  • Pip
  • 16 сообщений

Отправлено 15 декабря 2010 - 08:30

Я правильно понимаю, вы пытаетесь сравнить с Nil метод.
А сравнивать нужно объект - т.е в вашем случае метод должен возвращать объект.
Методы могут возвращать значения, отличные от Nil, если они объявлены как статические.
Как объявлен ваш метод?


Нет, вы неправильно понимаете. Это не указатель на функцию.
Метод возвращает ссылку на некоторый объект, пусть для определенности это будет System.Object, но может вернуть и null.
Если добавить obj в WatchList, и посмореть на значение obj после вызова метода, который возвращает null, то в WatchList-е не указывается ни тип, ни значение obj, но строка "if obj=nil then ..." не отрабатывает.
  • 0

#4 anagramma

anagramma

    Активный участник

  • Members
  • PipPip
  • 87 сообщений
  • Город:Moskow

Отправлено 15 декабря 2010 - 08:49

я проверяю существование объекта примерно так
Set MyObj  = Sys.Process('TestProcess')....

If Not MyObj is Nothing then
	'не пустой объект
ELSE
	'пустой объект
End IF

И обнуляю переменную объекта также
Set MyObj = Nothing

На delphi я думаю переведете.
  • 0

#5 Al_chimic

Al_chimic

    Новый участник

  • Members
  • Pip
  • 16 сообщений

Отправлено 15 декабря 2010 - 09:16

я проверяю существование объекта примерно так

Set MyObj  = Sys.Process('TestProcess')....

If Not MyObj is Nothing then
	'не пустой объект
ELSE
	'пустой объект
End IF

И обнуляю переменную объекта также
Set MyObj = Nothing

На delphi я думаю переведете.


Не работает:
Procedure test;
var 
  MyObj;
begin
    MyObj := Sys.Process('test');
    if MyObj=nil then
     Log.Message('пустой объект');
end;

  • 0

#6 Zenturio

Zenturio

    Опытный участник

  • Members
  • PipPipPipPip
  • 386 сообщений
  • ФИО:Дмитрий
  • Город:Смоленск - Москва


Отправлено 15 декабря 2010 - 10:47


я проверяю существование объекта примерно так

Set MyObj  = Sys.Process('TestProcess')....

If Not MyObj is Nothing then
	'не пустой объект
ELSE
	'пустой объект
End IF

И обнуляю переменную объекта также
Set MyObj = Nothing

На delphi я думаю переведете.


Не работает:
Procedure test;
var 
  MyObj;
begin
    MyObj := Sys.Process('test');
    if MyObj=nil then
     Log.Message('пустой объект');
end;


MyObj := nil;
if MyObj = nil then
Log.Message('пустой объект');

Данный код работает.
Следовательно ваш метод или объект возвращает не nil, а что либо другое.
Попробуйте использовать сравнение с varnull и unassigned
Второй вариант, попробывать выполнить преобразования.
Похоже что в нашем случае null это не Nil
Нужны преобразования
  • 0

#7 modbear

modbear

    Специалист

  • Members
  • PipPipPipPipPip
  • 548 сообщений

Отправлено 15 декабря 2010 - 11:26

В связи с этим вопрос, как обнулять ссылку на объект....

Так и обнулять - 
myVar := nil;
Вот только зачем? Локальные переменные, объявленные в процедуре, автоматически обнуляются по окончании этой процедуры.


... или, к примеру, вызывать методы из .Net Assembly c передачей в параметрах nil - в обоих случаях проводится неявное приведение к типу int со значением 0.

Скриптовые и .NET-овские типы могут быть не совместимы напрямую (разные технологии, разные внутренние реализации и т.п.)

Проблема с .NET null, кстати, уже обсуждалась. Предлагается получать null-значение из свойства/метода какого-нибудь .NET-класса, либо использовать в качестве null-значения объявленную, но неинициализированную переменную.  
  • 0

#8 Al_chimic

Al_chimic

    Новый участник

  • Members
  • Pip
  • 16 сообщений

Отправлено 15 декабря 2010 - 11:49

MyObj := nil;
if MyObj = nil then
Log.Message('пустой объект');

Данный код работает.
Следовательно ваш метод или объект возвращает не nil, а что либо другое.
Попробуйте использовать сравнение с varnull и unassigned
Второй вариант, попробывать выполнить преобразования.
Похоже что в нашем случае null это не Nil
Нужны преобразования


Данный код работает по следующей причине: в строке "MyObj := nil;" MyObj неявно приводится к типу Integer и переменной присваивается значение 0. А "if 0=0 then ..." ,понятное дело, срабатывает )
Убедиться в этом можно, добавив MyObj в WatchList
  • 0

#9 Al_chimic

Al_chimic

    Новый участник

  • Members
  • Pip
  • 16 сообщений

Отправлено 15 декабря 2010 - 11:59

Скриптовые и .NET-овские типы могут быть не совместимы напрямую (разные технологии, разные внутренние реализации и т.п.)

Через OLE могут

Проблема с .NET null, кстати, уже обсуждалась. Предлагается получать null-значение из свойства/метода какого-нибудь .NET-класса, либо использовать в качестве null-значения объявленную, но неинициализированную переменную.


Я сейчас делаю так. Объявляю переменную OleVariant и не инициализируюю ее. Если в метод надо передать null, передаю ссылку на эту переменную. Но как-то это через одно место получается.
  • 0

#10 Dmitry N

Dmitry N

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 742 сообщений
  • ФИО:Николаев Дмитрий
  • Город:Где-то в России

Отправлено 16 декабря 2010 - 09:10

Здравствуйте.

Что-то не получается у меня получить такую проблему с TestComplete 8.10. Следующий код в лог выводит 'True'.

DelphiScript:
procedure test;
var val;
begin
  val := dotNET.TestAss.TestClass.getNullValue;
  if val = nil then
    Log.Message('True')
  else
    Log.Message('False');
end;


C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestAss
{
  public class TestClass
  {
    public static object getNullValue()
    {
      return null;
    }
  }
}

  • 0
С уважением,
Дмитрий


Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных