我真的不理解,因为在我看来类型一致性的基础知识。我在Creation instruction lists explicit creation type which does not conform to type of target
上有一个create {JANITZA_DEVICE} l_device.make_from_file_path (a_file_path)
的埃菲尔Studio 19.5企业版。
class
SMA_INVERTER_MANAGER_CSV
inherit
SUNSPEC_DEVICE_CSV[SMA_INVERTER_MANAGER_DEVICE]
create
make
deferred class
SUNSPEC_DEVICE_CSV[G -> SUNSPEC_DEVICE create make_from_file_path end]
inherit
CONSUMPTION_SECTOR_CSV[G]
redefine
process_file,
set_header_csv
end
feature --
process_file (a_file_path: PATH)
require else
attached a_file_path.entry
attached consumption_sector
local
l_device: like devices.item
do
check
attached_consumption_sector: attached consumption_sector
then
if is_valid_file_path (a_file_path) then
if attached a_file_path.utf_8_name.has_substring ("janitza_UMG604") then
create {JANITZA_DEVICE} l_device.make_from_file_path (a_file_path) -- The compiler doesn't agree!
else
create l_device.make_from_file_path (a_file_path)
end
l_device.load_measuring_point (create_measuring_points, measuring_point_db_service, consumption_sector)
devices.extend (l_device)
Precursor (a_file_path) -- load measure_units from csv_row
devices.wipe_out
end
end
ensure then
devices.is_empty
end
deferred class
CONSUMPTION_SECTOR_CSV[G -> MEASURING_POINT_DEVICE]
feature -- Access
devices: LINKED_SET[G]
class
SUNSPEC_DEVICE
inherit
MEASURING_POINT_DEVICE
redefine
default_create,
set_measuring_point,
out
select
serial
end
MODBUS_DEVICE
rename
serial as modbus_serial,
set_serial as set_modbus_serial
undefine
make
redefine
default_create,
make_from_file_path,
name_from_file_path,
out
select
set_modbus_serial
end
create
make_from_file_path
class
JANITZA_DEVICE
inherit
SUNSPEC_DEVICE
redefine
set_measure_units,
name_from_file_path
end
create
make_from_file_path
答案 0 :(得分:2)
这是一个简化的情况:
class ANIMAL
class CAT inherit ANIMAL
class HOUSE_CAT inherit CAT
class DOG inherit ANIMAL
class
ENCLOSURE [G -> ANIMAL]
feature
specimens: LIST [G] --> The actual type will vary with the generic parameter
describe
do
print(specimens.generating_type)
end
class
APPLICATION
feature
test
local
l_cat: CAT
l_animal_enclosure: ENCLOSURE [ANIMAL]
l_cat_enclosure: ENCLOSURE [CAT]
l_house_cat_enclosure: ENCLOSURE [HOUSE_CAT]
l_dog_enclosure: ENCLOSURE [DOG]
do
create l_specimen
create l_animal_enclosure
l_animal_enclosure.describe --> LIST [ANIMAL]
l_animal_enclosure.specimens.add (l_cat) --> Fine, CAT conforms to ANIMAL
create l_cat_enclosure
l_cat_enclosure.describe --> LIST [CAT]
l_cat_enclosure.specimens.add (l_cat) --> Fine, CAT conforms to CAT
create l_house_cat_enclosure
l_house_cat_enclosure.describe --> LIST [HOUSE_CAT]
l_house_cat_enclosure.specimens.add (l_cat) --> ERROR, CAT does not conform to HOUSE_CAT
create l_dog_enclosure
l_dog_enclosure.describe --> LIST [DOG]
l_dog_enclosure.specimens.add (l_cat) --> ERROR, CAT does not conform to CAT
end
在您的情况下,devices: LINKED_SET [G]
太模糊了,没有任何证据表明JANITZA_DEVICE
是有效的类型,因为G
可能最终会降低层次结构(例如HOUSE_CAT
- > CAT
;您不能将CAT
替换为HOUSE_CAT
,因此HOUSE_CAT
的列表不能容纳CAT
)或在层次结构的单独分支中(例如DOG
-> ANIMAL
;狗不是猫,它们只有一个共同的祖先。)
如果将{ENCLOSURE}.specimens
声明为LIST [ANIMAL]
而不是LIST [G]
,则无论实际的通用参数如何,describe
都将始终打印LIST [ANIMAL]
,因为类型不会改变,因此先前的代码可以编译并正常运行。
同样,如果将{CONSUMPTION_SECTOR_CSV}.devices
声明为LINKED_SET [SUNSPEC_DEVICE]
而不是LINKED_SET [G]
,则无论SUNSPEC_DEVICE
的实际类型如何,它都可以容纳G
的所有后代。
或者,您可以将JANITZA_DEVICE
的特定部分从CONSUMPTION_SECTOR_CSV
移到CONSUMPTION_SECTOR_CSV
的后代,G
处于封闭状态,如
class
JANITZA_CONSUMPTION_SECTOR_CSV -- No generic here!
inherit
CONSUMPTION_SECTOR_CSV [JANITZA_DEVICE]
redefine
process_file -- Add the parts specific to `JANITZA_DEVICE` in the implementation
end
这将确保devices
可以容纳实例JANITZA_DEVICE
。
答案 1 :(得分:0)
我认为user10481525已经解释了错误的原因。您的代码不能保证JANITZA_DEVICE
的所有潜在后代中的G
都符合SUNSPEC_DEVICE_CSV
。
您已声明属性devices: LINKED_SET [G]
。因此,局部变量l_device: like devices.item
的类型为G
。在JANITZA_DEVICE
的后代中附加SUNSPEC_DEVICE_CSV
可能无效。为什么?因为G
可以是SUNSPEC_DEVICE
的任何后代。
例如,假设您有一个后代class FOO_DEVICE_CSV inherit SUNSPEC_DEVICE_CSV [FOO_DEVICE]
; class FOO_DEVICE inherit SUNSPEC_DEVICE
。您的本地变量将有效地解析为local l_device: FOO_DEVICE
。因此,后代将尝试将类型为JANITZA_DEVICE
的对象附加到该对象。但这是无效的,因为JANITZA_DEVICE
不符合FOO_DEVICE
:
feature devices: LINKED_SET [FOO_DEVICE]
...
local l_device: FOO_DEVICE
...
create {JANITZA_DEVICE} l_device.make_from_file_path (a_file_path) -- Invalid!