C# reflection get object from type - c#

I have a Type object.
I want to get the object isntance from this type. (just to use the ToString() method from this object).
see:
public class P
{
public string s;
}
class Program
{
static void Main(string[] args)
{
P p = new P();
p.s = "foobar";
Type t = p.GetType();
P p2 = ((t.ToObjet()) as P).s;
Console.WriteLine(p2.s);
}
}

Activator.CreateInstance is what you want.
Type givenType;
var obj = Activator.CreateInstance(givenType);
...
var obj = Activator.CreateInstance(givenType) as GivenType;
EDIT: Based on your edits, the extension method on Type you want (ToObject) is effectively the code above. It must create a new one because you can't be certain the source object still exists and even with the type, you could hit a scenario where that type has multiple instances.

You cannot get the instance back. The type is shared between all the instances, so what you want is impossible.
For example: if you know that something is an integer, you don't know which exactly value it has. (Integer is your type, value is a concrete instance.)

There is no way to do that. One reason is that GetType will return the same Type instance for all instances of the same type.
You can test this like so:
// this will print "True"
Console.WriteLine(object.ReferenceEquals("one".GetType(), "two".GetType()));
Calling GetType on those two different string instances returns the same Type instance, so it is clearly impossible to get one of them back based only on that Type instance.

Related

error "does not contain a definition for 'getProperty'" when trying to set property of generic typed object

void myFunc<M>()
{
dynamic uploadReq = (M)Activator.CreateInstance(typeof(M));
uploadReq.getProperty("Credentials").SetValue(null);
}
I have a function where I supply a type, an object of this type is created, and then a property on the object is set to null. I get an error
MyCustomType does not contain a definition for 'getProperty'
How can I fix this?
GetProperty its method of Type. Object has no it.
You can use this way:
call GetProperty from type
set value to object
public static void myFunc<M>()
{
dynamic uploadReq = (M)Activator.CreateInstance(typeof(M));
typeof(M).GetProperty("Credentials").SetValue(uploadReq, null);
}
In this specific snippet of code you don't need dynamic or reflection, because you know the type at compile time, just use the generic version of the CreateInstance method or even better the constructor of the type. This is faster and also provides compile time checks.
void myFunc<M>() where M : new()
{
M uploadReq = new M();
uploadReq.Credentials = null;
}
or
M uploadReq = Activator.CreateInstance<M>();
uploadReq.Credentials = null;

Array of objects - modyfing object's fields C#

I've got such a problem. I'm a beginner in C#.
I have an object array (various classes) and in one place of application I want to modify fields like an age or name. Construction
static Object[] prac = new Object[10];
public static void Main(string[] args)
{
prac[0].age = 21;
}
shouts an error
'object' does not contain a definition for 'age' and no extension method 'age' accepting a first argument of type 'object' could be found
I thought that will be similiar to a Java code, but it isn't. What am I doing wrong?
Regards.
You need to cast your member to the class type that contains the age. I'll just assume that your class name is Person and that is has a age member :
static Object[] prac = new Object[10];
public static void Main(string[] args)
{
((Person)prac[0]).age = 21;
}
Important to note are the brackets : (Person)prac[0] is the cast part, you cast the Object prac[0] to a Person object. The outer brackets ((Person)prac[0]) are there so that the code is taken as a Person object, instead of a regular Object.
First you need to cast the object to the type you're intending to work with.
If you work with type object, it has only a limited amount of properties and methods. To use property age, you first need to cast it to the corresponding type that has that property. For instance something like this:
static Object[] prac = new Object[10];
public static void Main(string[] args)
{
SpecificType myObject = prac[0] as SpecificType; // returns null if not successful
if (myObject != null)
myObject.age = 21;
}
HOWEVER, I'm not convinced you're doing the right thing here. I'd personally avoid type object unless absolutely there would be no other way of doing it (and that is very rare in my code). C# is a strongly-type language and by using object you're prone to errors all over the place.
Object doesn't have property age.
All Object's properties and methods are stated here.
It's an array of objects and as the error message suggests, 'object' does not contain a definition for 'age'
You need to declare your array with the type that has age field or property.And the you can modify it whatever you want. For example:
class Person
{
public string Name { get; set; }
}
You have to use an array of your class instead of Object which is the base type of all classes.
static MyClass[] prac = new MyClass[10];
or you have to cast it:
MyClass mc = (MyClass) prac[0];
mc.age = 21;
Object is the base class for all classes in .Net.
Just cast the required value to the required typed class. Or Create a list with the right type instead of object.

Create an instance of a custom generic class and a type stored in file as String

I am trying to create an instance of a generic class but my Type T of the generic class, i have gone through this link
http://msdn.microsoft.com/en-us/library/w3f99sx1(v=vs.110).aspx
but i couldn't find what i was looking for
i have this code
public class MyClass<T>
{
public T prop { get; set; }
}
and i have the type stored in string
the type
string typeString = "System.String";
now i want to use this type in myclass this way
Type xt = new Type.GetType(typeString);
MyClass<xt> obj = new MyClass<xt>();
but that just unidentified type xt
so what do i do!
The section Constructing an Instance of a Generic Type in the link provided covers this exact case.
In your case you would need write
Type typeArgument = Type.GetType(typestring);
Type constructed = typeof(MyClass<>).MakeGenericType(typeArgument);
object instance = Activator.CreateInstance(constructed);
However, the use cases of this techniques are far from common. You should try as much as possible to provide type information at compile-time. That is, try not to rely on Reflection to create your objects. Generics methods are especially useful for such cases.
The method Type.GetType(someString) gets the type at runtime, but generics class must be evaluated at compiled time. Between the <> symbols you need to specify the type itself and not an instance of the object Type. Something like this must work:
MyClass<String> obj = new MyClass<String>();
Thanks,

Type manipulation

Is it possible to create a method which returns a type and use it?
for example, assume I have a Person type and Object parameter.
As you probably know, If we want to cast our Object parameter, we can write:
object param;
((Person)param).executePersonMethod();
My question is how can I write a method which return Person type and use it instead the concrete Person cast - I want write something like this:
public Type GetPersonType()
{
//return here type of person
}
and then use
((GetPersonType())param).executePersonMethod();
Is it possible?
If yes, how?
You can use interface.
((IPerson)param).executePersonMethod();
each type of person must be an IPerson
and in IPerson you declare executePersonMethod()
You can also use dynamic for this.
Note that using dynamic will skip any compile time checking whether that method exists and will throw an exception at runtime if it doesn't.
Due to this risk, I would only do this if I have no other choice, but it's good to know that the option exists:
dynamic d = param;
d.executeWhateverMethodHereWithoutCompileTimeChecking();
Yes you can. There is a new type called dynamic which will avoid static type check during compilation.
public dynamic GetPersonOrObjectWhichHasExecutePersonMethod()
{
//return not the type but the object itself
return new Person();
}
public class Person
{
public void executePersonMethod()
{
// do something
}
}
// this is how you invoke it
public void ExecuteMethod()
{
dynamic obj = GetPersonOrObjectWhichHasExecutePersonMethod();
obj.executePersonMethod();
}
Maybe you can use something like that:
Convert.ChangeType(param, typeof(Person));
It would returns param as a Person.
You cannot execute methods on a Type, you can only execute methods on an instance of a particular Type. If I am understanding correctly, you should be able to use the answer #LavG gives to:
return not the type but the object itself from the GetPersonType method
Edit: As per your comment:
Here are some SO QA which will help you get the Type using fully
qualified namespace and other techniques:
How to get the type for a class by sending just the name of the class instead of the class itself as the parameter?
Type.GetType("namespace.a.b.ClassName") returns null
Here is how to generate a class from the given Type at run time:
generating a class dynamically from types that are fetched at runtime
Use
TypeOf()
Example :
if (data.GetType() == typeof(Personne))
return (Personne)data;
else
return new Personne();
After, check your object is not null to know if it's ok
Although you can use Generic as a better option, however it is possible using Type Convertor in combination with reflection:
Type type = GetPersonType();
var converted = Convert.ChangeType(param, type);
converted
.GetType()
.GetMethod(/*your desired method name in accordance with appropriate bindings */)
.Invoke(converted, /* your parameters go here */);

Returning desired type from Activator.CreateInstance() instead of object

I'm trying to create an instance of specified Type whatever user wants to have. For a quick illustration of my purpose please see the code below:
static void Main(string[] args)
{
object o = GetInstance(typeof(int));
Console.WriteLine("Created type: {0}", o.GetType().FullName);
}
public static object GetInstance(Type t)
{
Console.WriteLine("Creating instance of {0}", t.FullName);
return Activator.CreateInstance(t);
}
The problem is Activator.CreateInstance() returns object by default. There is also an overload of this method like T Activator.CreateInstance<T>() which is parameterless and returns the type you specify as T.
However, the problem is T should be hard-coded while calling this method and thus should be a fixed value. I am trying to create an instance of desired class and return it as its type.
Right now if you use this method you should write something like:
int i = GetInstance(typeof(int)) as int
I'm trying to reduce this to:
int i = GetInstance(typeof(int))
Is there a way that I can do casting inside the GetInstance and get rid of that as int repetition? By this way, my return type (and also the type I cast the object to) will be unknown at compile time.
Seemed impossible by design to me but I'd really appreciate if you figure it out.
EDIT: Where I'm stuck is e.g. while you're casting, you can do return (T) result if you are in a generic method, but you can't do Type t = ...; return (t) result this doesn't work. You cannot cast to a type which is passed to you as a parameter which is not known at compile time.
Follow a known pattern
This is not a new problem. It is a problem facing any API that allows type-specific return values. For example, a JSON parsing library like Newtonsoft (which is, to wit, the single most popular .NET package downloaded by .NET programmers in 2019) must be able to parse a string and return a type-specific object, which may or may not be known at compile time. It might make sense to follow their example.
Newtonsoft exposes three ways to specify the type when deserializing. You could do as you are currently doing:
//Cast required
var result = JsonConvert.DeserializeObject(text, typeof(MyType)) as MyType;
You can use a generic method:
//No cast required, but you have to hardcode a type as a type parameter
var result = JsonConvert.DeserializeObject<MyType>(text);
Or you can use an instance as a template, which is great for anonymous types, although you can use it with non-anonymous classes as well. This one works via generic type inference:
//No cast required and no need to specify type; the type is inferred from the argument
var result = JsonConvert.DeserializeAnonymousType(text, new MyType());
Here's how you'd do it:
So for you to make this work, your code might look like this:
public object GetInstance(Type type)
{
return Activator.CreateInstance(type);
}
int i = GetInstance(typeof(int)) as int;
public T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
int i = GetInstance<int>();
public T GetInstance<T>(T template)
{
return Activator.CreateInstance<T>();
}
int i = GetInstance(0);
If you do it this way, it's hard to imagine any programmer would have trouble using your library, as the approach should already be familiar to them.
Actually you could write GetInstance like this:
static T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
And use it:
int j = GetInstance<int>();
This might help you to create instance of desired type:
public class ConcreteFactory<T> : AbstractFactory<T>
{
public override T CreateInstance(string typeName,params object[] parameters)
{
var path = Assembly.GetExecutingAssembly().CodeBase;
var assembly = Assembly.LoadFrom(path);
var type = assembly.GetTypes().SingleOrDefault(t => t.Name == typeName);
return (T)Activator.CreateInstance(type, parameters);
}
}
Key here is generic type T can be used to cast the created instance, this can be used as a template to create instance of any type with parameterized constructor

Categories

Resources