Where is your instance of customer declared? And created? As in:
Var wiggy as customer // Tell the compiler what wiggy is
wiggy = new customer // Give wiggy an actual instance
Then you have to have some data to shove into the instance, as in:
wiggy.FirstName = "Joe"
wiggy.LastName = "Bloggs"
Etc.
Creating the class allows the compiler to know what you’re talking about, but until you actually create one and fill in its properties, it’s like having it written on a bit of paper. Nothing more.
function SetPropertyByName(name as string, value as variant)
Select case name
case "FirstName"
me.firstName = value
case "LastName"
me.lastName = value
...
end select
end function
Based on what you have asked, I think you want to use Introspection, which will let you loop through all the properties of a class to determine their names.
I am using introspection and have no problem getting and looping through the properties, my problem is passing the property name as a variable like the fld variable in customer.value(fld = “Tim”)
Here’s some code I wrote a while back to do this using Introspection:
Function SetPropertyByName(extends o as object, name as string, newVal as variant)
' given an object instance, and a property name, such as "firstName"
' finds a property with the same name, and sets it to the value newVal
' has some error checking for invalid combinations, but may not catch every illegal situation
#pragma DisableBackgroundTasks
dim props() as introspection.PropertyInfo = Introspection.getType(o).GetProperties // warning, can cause thread yield here!!!
dim p as introspection.PropertyInfo
for each p in props
if p.name = name then
' we found the property with the same name,
' lets do some error checking before setting the value
' type-safety when assigning
dim t1 as Introspection.TypeInfo = p.propertyType
if t1 is nil then
system.debugLog CurrentMethodName + " t1 = nil"
raise new NilObjectException
end if
if newVal is nil or newVal.type = Variant.TypeObject then
system.debugLog CurrentMethodName + " invalid object assignment " + name
raise new TypeMismatchException
if t1.IsPrimitive or t1.isEnum then
' object or nil can not be assigned to primitive
system.debugLog "SetPropertyByName: object type mismatch : " + t1.fullname + " <> " + newVal.StringValue
raise new TypeMismatchException
else
' do the object types match?
dim t2 as Introspection.TypeInfo = Introspection.getType(newVal.ObjectValue) // note: will be nil if it's a basic type (string, integer, etc.)
if t2 is nil then
system.debugLog CurrentMethodName + " t2 = nil"
raise new NilObjectException
end if
if t1.fullName <> t2.fullName then
system.debugLog "SetPropertyByName: object type mismatch : " + t1.fullname + " <> " + t2.fullName
raise new TypeMismatchException
end if
end if
else
// newVal is a primitive or enum
if t1.IsEnum then
// ok
elseif t1.IsPrimitive then
' variant primitive -> primitive or enum is OK
elseif not (newVal is nil) then
' variant primitive -> object : not allowed
system.debugLog "SetPropertyByName: object type mismatch : " + t1.fullname + " <> " + newVal.StringValue
raise new TypeMismatchException
end if
end if
' if we reach here, it should be OK, so set the value now
p.value(o) = newVal
return
end if
next
' if we get here, we failed to find matching property name
system.DebugLog "Object.SetPropertyByName: missing property : " + name
break
raise new InvalidArgumentException
end function
PropertyInfo.name is a string - if the property is MyClass.FirstName then it’s propertyInfo will be a string “FirstName” so you can just match on that. See my code above.
Edit to add - if you use my function above, then your code would be quite simple:
var fld as string="FirstName"
customer.SetPropertyByName(fld, "Tim")
it could even be done in a single line:
customer.SetPropertyByName("FirstName", "Tim")
The main disadvantage to using Introspection? It is slow - possibly 10x or 100x slower than setting the property directly. If you have a lot of data and need high performance, the Switch/Case example above will be much faster.
We created a Meta class that, upon instantiation, stores the Introspection.PropertyInfo in a Dictionary upon first instantiation, then stores the Meta in a shared property. To set that property, we then do something like:
var pi as Introspection.PropertyInfo = Class.Meta.Value( "FirstName" )
pi.Value( Class ) = newValue
I am trying to wrap my head around this meta class thing I understand how to get the property info into a dictionary upon instantiation. I guess I am at a loss with the whole shared properties coding methods.
I believe that Kem’s solution is an optimization of my solution, which avoids having to loop over all the propertyInfo object array every time you make an assignment.
Technical info: looping over a list or an array to find an item in it takes longer as the array grows longer, where N is the # of items in the list. This is called Order N or O(N) under the Big O Notation
Dictionarys tend to have a (mostly) constant time for accessing an item, regardless of how many items are in the dictionary.
This is called constant, Order 1 or O(1).
I would not worry about this for now, unless you have poor performance using my solution.
If that happens, come back and @Kem_Tekinay will solve it for you