RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Some question of C#

Kaon

Wanderer
Some question of C#

First Question : typeof(classX) -> typeX ... Y(typeX) -> classX
Here is my problem : I know how to get the type of a class or an instance. For this, using typeof(MyClass) or MyInstance.GetType() works great.

But, know, I am facing a problem : I want to call a templated function with the type of instance ... MyFunction<ClassOfMyInstance>(MyInstance)

Is there a keyword that do the opposite of typeof ?

---------------------

Second question :
I have a generic List (List<Something>). How to get the type Something with the instance of my List ? :)

----------------------
Thanks
 

Kaon

Wanderer
For the first question, here's what I want to do :
I have an instance of a List<Something> called for example toto. I can get the Type object of "Something" by get through the toto.GetType().GenericParameters (or a property approching this, it is the answer to my second question of my first post ;))

Now, I want to call a method MyMethod<T>(object blah), with the parameters I found : MyMethod<Something>(toto)

But, I don't want to do a succession of "if" condition to catch all type that can be "Something" ...

I know that typeof(Something) return the Type object of "Something"
Now, I just want a way to reverse this : how to get the "Something" from the Type object of "Something" ? :D

Or, in my case, how to call my generic method with a type I don't know ? :p
 

daat99

Moderator
Staff member
Kaon;697363 said:
For the first question, here's what I want to do :
I have an instance of a List<Something> called for example toto. I can get the Type object of "Something" by get through the toto.GetType().GenericParameters (or a property approching this, it is the answer to my second question of my first post ;))

Now, I want to call a method MyMethod<T>(object blah), with the parameters I found : MyMethod<Something>(toto)

But, I don't want to do a succession of "if" condition to catch all type that can be "Something" ...

I know that typeof(Something) return the Type object of "Something"
Now, I just want a way to reverse this : how to get the "Something" from the Type object of "Something" ? :D

Or, in my case, how to call my generic method with a type I don't know ? :p
Do you have an actual object in the list or is it just a list of object types?
If so, do you want to execute the method for that particular object?

Assuming both answers are yes you can do something like this:
Code:
try
{
	//get the method that we want based on its name (executeName) that expect 1 argument of type "CommandParameters" (an object)
	//ecType is the type of the object you want to execute the method for
	MethodInfo method = ecType.GetMethod(executeName, new Type[] { typeof(CommandParameters) }); 
	//execute the method by sending it the object it expects and return the value it returns to the caller
	return (bool)method.Invoke(null, new object[] { command });
}
catch (Exception ex)
{
	//it failed, throw the exception (crash the shard) up the line
	//if you know how to handle the exception then do so here instead of throwing the exception so it won't crash the shard
	throw ex;
}


Hope that helps ;)
 

Jeff

Lord
I really don't understand, perhaps you should show us some code, it still sounds to me that you are refering to the oposite of typeof(object) would be an instance of that object. I would need to see code as to what you are doing to help you further.
 

Kaon

Wanderer
Interesting!

Thanks ZixThree, you put me on the path to the solution I guess ;)
I'll try to use System.Reflection.MethodInfo.MakeGenericMethod and post if it works (or not ^^) in a few days

Thanks daat99 and Jeff to, Reflection is not yet my "cup of tee", so it's always good to read documentation about it :)
 

Jeff

Lord
Kaon;697467 said:
Interesting!

Thanks ZixThree, you put me on the path to the solution I guess ;)
I'll try to use System.Reflection.MethodInfo.MakeGenericMethod and post if it works (or not ^^) in a few days

Thanks daat99 and Jeff to, Reflection is not yet my "cup of tee", so it's always good to read documentation about it :)

Something to consider, Reflection is slow and resource hungry, avoid it whenever possible.
 

Kaon

Wanderer
Ok, I've tested some things, and now I'm faced to a error I can't explain : "wrong parameters count"

Code:
Exception:
System.Reflection.TargetParameterCountException: Nombre de paramètres incorrects.
   à System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
   à System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   à System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   à System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
   à Server.Gumps.ASetListGump`1..ctor(PropertyInfo prop, Mobile mobile, Object o, Stack stack, Int32 page, ArrayList list)
   à Server.Gumps.ASetListGump`1.InternalTarget.OnTargetFinish(Mobile from)
   à Server.Targeting.Target.Invoke(Mobile from, Object targeted)
   à Server.Network.PacketHandlers.TargetResponse(NetState state, PacketReader pvSrc)
   à Server.Network.MessagePump.HandleReceive(NetState ns)
   à Server.Network.MessagePump.Slice()
   à Server.Core.Main(String[] args)

Here is the code :
Code:
public ASetListGump(PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list) : base(GumpOffsetX, GumpOffsetY)
{
[...]
            object lst = prop.GetValue(o,null);
            int count = (int)lst.GetType().GetProperty("Count").GetValue(lst, null);
[...]
            for (int i = 0, k=1; i < count; ++i)
            {
[...]
                object test = prop.GetValue(o, new object[] { i });
[...]
            }
[...]
}
It crashes on this line :
object test = prop.GetValue(o, new object[] { i });

o is an object with a property of type List<Item>. When the list is empty, it works (normal, it doesn't enter the for iteration) ... there is a "i" index, because of Count property.

I've "googled" a lot, but all example I found is like I wrote :(
Any ideas?
 

Sep102

Page
Umm, it looks like you might be getting a little mixed up there and that would be the problem.

The PropertyInfo parameter "prop" (I would assume from your explanation) is used to access some property of the Object "o" that returns an object of type List<Item>, which is not an indexer (as in, it isn't a property that takes any arguments), so passing null for the arguments in the first prop.GetValue() line works fine and gets the list like it's supposed to.

However, then you attempt to use the PropertyInfo again on "o" to get at the elements of the list, which isn't working (and thus causing an exception) because it's attempting to pass an argument to a property that does not have any parameters.

Now, what you might have meant to do is make the second call to GetValue() with "lst" as the object rather than "o", but that still wouldn't work and would also throw an exception (of System.Reflection.TargetException, assuming o's type is not a subtype of List<Item>).

What I assume you were trying to do was to access the default property of the list object (i.e. the one that allows you to put list_name[0] to retrieve the first element), which means (I'm assuming you want to keep it generic, so I'm not going to suggest casting) that you'll need to create a new PropertyInfo that gets the property "Item" of the lst object's type (assuming the type uses the default name for the default property, which List does), then use that PropertyInfo with the call to GetValue() and pass "lst" instead of "o".
 

Kaon

Wanderer
the Object "o" that returns an object of type List<Item>, which is not an indexer (as in, it isn't a property that takes any arguments)
A property (get/set) never takes arguments, unless it is a array type and use to access index ... no? How do you declare a indexer ? What it is? :/ (just to know, disgression of the actual problem ^^)


What I assume you were trying to do was to access the default property of the list object (i.e. the one that allows you to put list_name[0] to retrieve the first element), which means (I'm assuming you want to keep it generic, so I'm not going to suggest casting) that you'll need to create a new PropertyInfo that gets the property "Item" of the lst object's type (assuming the type uses the default name for the default property, which List does), then use that PropertyInfo with the call to GetValue() and pass "lst" instead of "o".
(exactly what I want ^^)
I searched such a property with name "this" ( public T this[int index] { get; set; }) or others in the metadata definition of List<> ... And I checked again the metadata, and can't find the Item Property ... where is it defined ? I checked the herited classes too :/

Without testing, the first thing coming up to my mind is that it won't find any property with the name "Item" :/
Can you explain a litlle bit more ? :D

Waiting to know more on this point, I used to call the GetEnumerator() methods, and cast it to a IEnumerator ... It works for the moment, but I guess I'll be limited on the futur with this ...
 

Sep102

Page
Sorry, guess I should have explained a few terms better.

Kaon said:
A property (get/set) never takes arguments, unless it is a array type and use to access index ... no? How do you declare a indexer ? What it is? :/ (just to know, disgression of the actual problem ^^)

An indexer is a property that "is a array type and use to access index", it's one of the many names for properties that are accessed as "" (which, as I stated, is a property that takes arguments, likewise you could have a property that takes two arguments and access it as "[i1, i2]"). And, as you probably know already (knowing what an indexer is now) you declare an indexer like "public Int32 this[Int32 index] ..."

Kaon said:
(exactly what I want ^^)
I searched such a property with name "this" ( public T this[int index] { get; set; }) or others in the metadata definition of List<> ... And I checked again the metadata, and can't find the Item Property ... where is it defined ? I checked the herited classes too :/

Without testing, the first thing coming up to my mind is that it won't find any property with the name "Item" :/
Can you explain a litlle bit more ?
If you used Visual Studio's Object Browser to look for it, then you're correct, you won't find an Item property in List (however you will if you use Reflector to browse classes, which, by the way, is quite an invaluable tool). As I said, it does have an Item property, as that is the default name that it gives to a class's array properties. So, while you won't be able to find it in the Object Browser, it does exist, and is the way you access the array property when using Type.GetProperty() (so, to access List's this[Int32] property, you would use prop2 = lst.GetType().GetProperty("Item"), then you could access it the way that you were trying to).
 
Top