I’d like to add that performance-wise, you should cache the results of :GetPropertiesOfClass() because it doesn’t do that internally and is quite slow.
local ReflectionService = game:GetService("ReflectionService")
local classPropertiesCache = {}
local function cacheClassProperties(className : string) : ()
local cachedProperties = {}
for _, v in ReflectionService:GetPropertiesOfClass(className) do
cachedProperties[v.Name] = v
end
classPropertiesCache[className] = cachedProperties
end
local function safeRead(instance : Instance, property : string) : any
if not classPropertiesCache[instance.ClassName] then
cacheClassProperties(instance.ClassName)
end
local hasProperty = classPropertiesCache[instance.ClassName][property] ~= nil
if hasProperty then
return instance[property]
end
return nil
end