Casting to types that are know only at Runtime by their string names. C# - string

I've got a problem here. (C#)
There's a collection in another assembly (I cannot change it) that takes a string as parameter and returns an object.
Like:
object Value = ThatCollection.GetValue("ParameterName");
The problem is, for each parameter string, it returns a DIFFERENT type as object.
What I want is to cast those objects to their respective types, knowing the types only at runtime by their string names.
I need to do some operations with those returned values.
And for that I need to cast them properly in order to access their members and so.
Limitations:
I cannot use "dynamic" since my code needs to be done in an older framework: 3.5 (because of interop issues).
I need to do operations with MANY returned values of different types (no common interfaces nor base classes, except "object", of course)
All I have is a table (containing string values) correlating the parameter names with their returned types.
Yes, I could transform that table into a biiig "switch" statement, not very nice, don't want that.
Any hints??

You want to look into reflection, something like the following should work to cast an object to type T. Set up a simple cast method:
public static T CastToType<T>(object o)
{
return (T)o;
}
Invoke this using reflection:
Type t = Type.GetType(stringName)
MethodInfo castTypeMethod = this.GetType().GetMethod("CastToType").MakeGenericMethod(t);
object castedObject = castTypeMethod .Invoke(null, new object[] { obj });

Related

How to use EncodedObjectAsID?

I'm trying to understand get_instance_id()
and I came across this line in the documentation:
This ID can be saved in EncodedObjectAsID, and can be used to retrieve
the object instance with #GDScript.instance_from_id.
I can't seem to understand what this statement means exaclty and how to use EncodedObjectAsID, could someone please provide a working example?
The EncodedObjectAsID follows a pattern called Boxing. Boxing is where you put a primitive value, like an int, into an object. This boxed primitive can now be used in an object oriented way. For example, you can pass the boxed int to a function that only takes objects (i.e. it applies Polymorphism):
func only_takes_object(obj: Object)
only_takes_object(123) # Error
var box = EncodedObjectAsID.new()
box.object_id = 123
only_takes_object(box) # Valid
This is how parts of the editor use the EncodedObjectAsId object.
In marshalls.cpp we can see that an encoded Object may be an integer ID or the whole object. When it is flagged as only an integer ID a EncodedObjectAsID object is created. This object is then converted to a Variant.
When adding a stack variable in editor_debugger_inspector.cpp a variant with a type of object is assumed to be and converted to an EncodedObjectAsID to fetch the referenced object's id.
Here's two more links that follow a similar pattern:
array_property_edit.cpp
scene_debugger.cpp
Note that Variant can be implicitly converted to an Object and Object::cast_to() only takes Objects.
This ID can be saved in EncodedObjectAsID, and can be used to retrieve the object instance with #GDScript.instance_from_id.
This sentence should be split into two independent clauses. It should read as
"The instance ID can be saved in an EncodedObjectAsID."
"The instance ID can be used to retrieve the object instance with #GDScript.instance_from_id()."
Note: You should not store an object's id in storage memory. There is no guarantee that an object's id will remain the same after restart.

How to obtain data type directly? [duplicate]

Is there a way to determine the Object type, when passing a reference to a function?
I'm using a security permissions function, which determines if the user has permission to view/edit the Form passed to it by reference. I'd like to expand this to include reports as well.
To keep the function generic, I'd like to pass a ref for either a Form or a Report as an Object, eg:
function gfSecurity_Permission(obj as Object)
However, I'd need to determine the type of the object within the function.
Does anyone know of a way to do that?
MTIA
Take a look at
typeOf and typeName
Generic object variables (that is, variables you declare as Object)
can hold objects from any class. When using variables of type Object,
you may need to take different actions based on the class of the
object; for example, some objects might not support a particular
property or method. Visual Basic provides two means of determining
which type of object is stored in an object variable: the TypeName
function and the TypeOf...Is operator.
TypeName and TypeOf…Is
The
TypeName function returns a string and is the best choice when you
need to store or display the class name of an object, as shown in the
following code fragment:
Dim Ctrl As Control = New TextBox
MsgBox(TypeName(Ctrl))
The TypeOf...Is operator is the best choice for testing an object's
type, because it is much faster than an equivalent string comparison
using TypeName. The following code fragment uses TypeOf...Is within an
If...Then...Else statement:
If TypeOf Ctrl Is Button Then
MsgBox("The control is a button.")
End If
Simplest way to determine the access type in access is to do an object lookup within the Access' system tables.
Here would be the lookup:
DLookup("Type","MSysObjects","NAME = '" & strObject & "'")
strObject is the name of the object within Access
The result is one of the number below OR NULL if the object does not exist in Access
1 = Access Table
4 = OBDB-Linked Table / View
5 = Access Query
6 = Attached (Linked) File (such as Excel, another Access Table or query, text file, etc.)
-32768 = Access Form
-32764 = Access Report
-32761 = Access Module
so, the dlookup would provide "-32768" for a Form or "-32764" for a Report
Hope that helps

In Groovy, casting between collection implementations copies source instead

The following code
void testReference() {
List<String> source = new ArrayList<>()
source.add("element")
List reference = (ArrayList)source // all ok, creates reference as types match
assertSame(source,reference)
List copyNotReference = (LinkedList)source // should fail on GroovyCastException, creates copy instead
assertNotSame(source,copyNotReference) // this works, copy is a different object
copyNotReference.add("second element")
println source
println copyNotReference
}
only works in Groovy. In Java it fails on attempt to cast ArrayList to LinkedList.
In Groovy it creates a LinkedList instance, calling constructor
public LinkedList(Collection<? extends E> c)
and copying source data to the new instance.
The test outputs
[element]
[element, second element]
That behaviour only occurs when casting types that are subtypes of collections.
Question
What Groovy mechanism is responsible for this unexpected behaviour?
Groovy allows coercion of objects via casting them (asType). This is implemented for collections.
See the source
Converts the given collection to another type. A default concrete
type is used for List, Set, or SortedSet. If the given type has
a constructor taking a collection, that is used. Otherwise, the
call is deferred to {#link #asType(Object,Class)}. If this
collection is already of the given type, the same instance is
returned.

what's the meaning of "type tags" in nodejs

assert.deepStrictEqual(actual, expected[, message]) in nodejs's docs:
Type tags of objects should be the same.
what's the meaning of "type tags"
const date = new Date();
const object = {};
const fakeDate = {};
Object.setPrototypeOf(fakeDate, Date.prototype);
// Different type tags:
assert.deepStrictEqual(date, fakeDate);
typeof date and typeof fakeDate ,The results are all object, but different type tags
Type tags in Javascript, are referred to the word returned by typeof
For example for primitive values:
typeof({}) // returns 'object', this is the type tag
For non-primitive:
Object.getPrototypeOf(new Date) // returns 'Date {}' this is the type tag
If typeof is used with Date it will returns object which is right, because that would be the type tag for the primitive value, this is why using Object.getPrototypeOf is more accurate.
In the firsts JS implementations, the type tag were stored the first 1–3 bits and the the remaining 29–31, contained the actual data.
What the NodeJS docs says, it's that the result of Object.getPrototypeOf function when comparing two objects has to be the same to be considered as equal.
This is an old question that has been already answered, but I thought I might add that, although:
In the first implementation of JavaScript, JavaScript values were
represented as a type tag and a value. The type tag for objects was 0.
null was represented as the NULL pointer (0x00 in most platforms).
Consequently, null had 0 as type tag, hence the typeof return value
"object".
Type tags can also refer to an object's toStringTag.
The Symbol.toStringTag well-known symbol is a string valued property
that is used in the creation of the default string description of an
object. It is accessed internally by the Object.prototype.toString()
method.
The value associated to the well-know Symbol.toStringTag is used as the default string description of an object. Since every built-in object has a toStringTag value (except for null prototypes), it can be used to detect an object's class.
There's a package called typetags that has more information about it: typetags.org

Groovy type conversion

In Groovy you can do surprising type conversions using either the as operator or the asType method. Examples include
Short s = new Integer(6) as Short
List collection = new HashSet().asType(List)
I'm surprised that I can convert from an Integer to a Short and from a Set to a List, because there is no "is a" relationship between these types, although they do share a common ancestor.
For example, the following code is equivalent to the Integer/Short example in terms of the
relationship between the types involved in the conversion
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
def c = new Child1() as Child2
But of course this example fails. What exactly are the type conversion rules behind the as operator and the asType method?
I believe the default asType behaviour can be found in: org.codehaus.groovy.runtime.DefaultGroovyMethods.java
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.java.
Starting from DefaultGroovyMethods it is quite easy to follow the behavior of asType for a specific object type and requested type combination.
According to what Ruben has already pointed out the end result of:
Set collection = new HashSet().asType(List)
is
Set collection = new ArrayList( new HashSet() )
The asType method recognizes you are wanting a List and being the fact HashSet is a Collection, it just uses ArrayList's constructor which takes a Collection.
As for the numbers one, it converts the Integer into a Number, then calls the shortValue method.
I didn't realize there was so much logic in converting references/values like this, my sincere gratitude to Ruben for pointing out the source, I'll be making quite a few blog posts over this topic.

Resources