|
You last visited: Today at 05:12
Advertisement
Generic Variables/Classes
Discussion on Generic Variables/Classes within the CO2 Programming forum part of the Conquer Online 2 category.
07/04/2013, 08:36
|
#1
|
elite*gold: 80
Join Date: Sep 2007
Posts: 642
Received Thanks: 168
|
Generic Variables/Classes
Hello,
I'm just trying to figure out how I want to do a few things that I am working on my custom source. I have run into two instances which a generic variable would have been a very handy.
I have tried doing something like the following in hopes to use a dictionary to contain this class as the value, but when defining the dictionary it wanted the type right then.
Code:
public class MyClass<T>
{
string Section;
string Key;
T Value;
}
Dictionary<string,MyClass<T>> Dic //Wanted me to define the type of class it would be.
My question is, does anyone know of anything that will sort of achieve what I am trying to do? I'm trying to avoid writing multiple methods for the different types.
Please let me know if I didn't do a good job describing what I am trying to do.
Thanks
Greg.
|
|
|
07/04/2013, 09:36
|
#2
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,376
|
Your issue is because you're not telling it what type of data it will be storing.
Collections need to be told when declared what type of objects they will be storing. As such your collection can only hold one type of MyClass properly (EG: MyClass<uint>)
That being said you could have it store any type of base class in order to store multiple types but it all really depends on what you're trying to accomplish. If you could be a bit more clear we can probably provide some more help.
Example of base class holding different object types.
public class MyClass<T>
{
T value;
}
Dictionary<uint, MyClass<ILocatableObject>> objectCollection;
You could then use anything inheriting from ILocatable object and access it via MyClass.value although you'd need to type check and cast it based on your needs if you require details past the initial ILoc interface.
Anyways, let us know what it is you're trying to do and we can be a touch more specific.
|
|
|
07/04/2013, 10:05
|
#3
|
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
|
the biggest weakness about generics in C# is that they're strong (typed; pun intended).
you'll find out most of what u want to know about how to use them, purposes, etc. here:
the only thing that they don't mention is as i mentioned above, they're strong-typed, but it turns out this is enforced by the C# compiler, and is not true at the IL level, for instance, sizeof(T) is not valid in C#, however, hacking the IL we can create our own sizeof() function that works on generic types, for more..
|
|
|
07/04/2013, 13:29
|
#4
|
elite*gold: 80
Join Date: Sep 2007
Posts: 642
Received Thanks: 168
|
Quote:
Originally Posted by pro4never
Your issue is because you're not telling it what type of data it will be storing.
Collections need to be told when declared what type of objects they will be storing. As such your collection can only hold one type of MyClass properly (EG: MyClass<uint>)
That being said you could have it store any type of base class in order to store multiple types but it all really depends on what you're trying to accomplish. If you could be a bit more clear we can probably provide some more help.
Example of base class holding different object types.
public class MyClass<T>
{
T value;
}
Dictionary<uint, MyClass<ILocatableObject>> objectCollection;
You could then use anything inheriting from ILocatable object and access it via MyClass.value although you'd need to type check and cast it based on your needs if you require details past the initial ILoc interface.
Anyways, let us know what it is you're trying to do and we can be a touch more specific.
|
Pro, I understand that I need to tell it what type I want to store but the thing is, I want to be able to store multiple types in a dictionary.
When it comes down to type checking an object would it mistake, say, a ushort for a uint when converting back. From my quick testing it doesn't seem the mistake them, but would it be possible you think? Such as:
Code:
ushort _short = 2345;
object _obj = _short;
if(_obj is uint) = true
Basically I'm trying to use this with my database system of sorts. My Idea is not to update the database until they log off but I don't want to save everything if it wasn't changed. I'm thinking of using the dict for a sort of queue, which will be looped through to save all changed variables. I have a messy way implemented already but was just trying to play around will different idea, as I don't like how messy it turned out.
I don't know why it never crossed my mind to store the value as an object and just type check it later. I'm going to mess with that more tomorrow.
Quote:
Originally Posted by InfamousNoone
the biggest weakness about generics in C# is that they're strong (typed; pun intended).
you'll find out most of what u want to know about how to use them, purposes, etc. here:
the only thing that they don't mention is as i mentioned above, they're strong-typed, but it turns out this is enforced by the C# compiler, and is not true at the IL level, for instance, sizeof(T) is not valid in C#, however, hacking the IL we can create our own sizeof() function that works on generic types, for more..
|
Thanks for the links. So "hacking" the IL you can make a strong typed variable weaker?
Thanks guys.
Greg
|
|
|
07/04/2013, 17:22
|
#5
|
elite*gold: 0
Join Date: Dec 2012
Posts: 1,761
Received Thanks: 946
|
"I don't know why it never crossed my mind to store the value as an object and just type check it later. I'm going to mess with that more tomorrow."
It's called boxing and unboxing.
|
|
|
07/04/2013, 19:51
|
#6
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,376
|
Quote:
Originally Posted by StarBucks
Basically I'm trying to use this with my database system of sorts. My Idea is not to update the database until they log off but I don't want to save everything if it wasn't changed.
Greg
|
I feel NHibernate or a similar system will be far more efficient as well as user friendly.
Even if you have everything working properly in this custom system of yours you'd still be executing multiple queries, lots of checking going on, etc.
Personally I use the NHibernate Domain objects as the private members of my classes with public assessors to update them.
When the user logs out? Just AddOrUpdate the entity's database entry with no extra type checking and all done in one quick easily managed query.
eg
DbCharacter characterInfo
public byteLevel{get {return characterInfo.Level; } set { characterInfo.Level = value; Send(new UpdatePacket(UID, UpdateType.Level, value);}}
All of the mapping already has the object types stored which match up properly with the table itself and then you only save when you kick or logout the user. Bit off topic but for that I use a static UserManager which tracks all connected clients. From there you can easily handle login/logout actions, querying players by id/name/etc as well as things like saving all players for shutdown.
|
|
|
07/04/2013, 22:45
|
#7
|
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
|
Quote:
Originally Posted by StarBucks
Pro, I understand that I need to tell it what type I want to store but the thing is, I want to be able to store multiple types in a dictionary.
|
Use a union.
Code:
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public int Int;
[FieldOffset(0)]
public bool Bool;
[FieldOffset(0)]
public DateTime Time;
// note you must be aware of the sizes of your pure structures above
// to get this offset right, max(sizeof(Int), ..., sizeof(DateTime)) = 8
[FieldOffset(8)]
public object Obj;
[FieldOffset(8)]
public string Str;
[FieldOffset(8)]
public string[] Strings;
}
your pure structures (structures that only consist of other structures, i.e. a Tuple<string, int> isn't a pure structure) must be grouped at one offset, and your objects must grouped at another.
|
|
|
07/04/2013, 22:51
|
#8
|
elite*gold: 80
Join Date: Sep 2007
Posts: 642
Received Thanks: 168
|
Quote:
Originally Posted by pro4never
I feel NHibernate or a similar system will be far more efficient as well as user friendly.
Even if you have everything working properly in this custom system of yours you'd still be executing multiple queries, lots of checking going on, etc.
Personally I use the NHibernate Domain objects as the private members of my classes with public assessors to update them.
When the user logs out? Just AddOrUpdate the entity's database entry with no extra type checking and all done in one quick easily managed query.
eg
DbCharacter characterInfo
public byteLevel{get {return characterInfo.Level; } set { characterInfo.Level = value; Send(new UpdatePacket(UID, UpdateType.Level, value);}}
All of the mapping already has the object types stored which match up properly with the table itself and then you only save when you kick or logout the user. Bit off topic but for that I use a static UserManager which tracks all connected clients. From there you can easily handle login/logout actions, querying players by id/name/etc as well as things like saving all players for shutdown.
|
I have looked into NHibernate and from my understanding it will not apply to my application. I'm trying to keep my "database" flat file for portability because I develop on multiple computers on a given day. I'm trying to avoid having to install anything unless of course It is also portable. SQLite might have some portability but i haven't looked into that yet.
As I expected, just saving all variables when the player logs off is way faster than queueing the changed ones with my current system. I'm going to try a few different things to see if I can get something thats comparable.
|
|
|
07/05/2013, 00:07
|
#9
|
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,376
|
Quote:
Originally Posted by StarBucks
I have looked into NHibernate and from my understanding it will not apply to my application. I'm trying to keep my "database" flat file for portability because I develop on multiple computers on a given day. I'm trying to avoid having to install anything unless of course It is also portable. SQLite might have some portability but i haven't looked into that yet.
As I expected, just saving all variables when the player logs off is way faster than queueing the changed ones with my current system. I'm going to try a few different things to see if I can get something thats comparable.
|
Flat file and efficiency never really go in hand but assuming you're doing a flatfile for that specific character then you could always just do a tostring overload to return the flatfile contents for that character instance and then write it to a file.
It's not what you're looking for but it would be pretty **** simple and easy to understand.
|
|
|
07/05/2013, 02:27
|
#10
|
elite*gold: 80
Join Date: Sep 2007
Posts: 642
Received Thanks: 168
|
Quote:
Originally Posted by InfamousNoone
Use a union.
Code:
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)]
public int Int;
[FieldOffset(0)]
public bool Bool;
[FieldOffset(0)]
public DateTime Time;
// note you must be aware of the sizes of your pure structures above
// to get this offset right, max(sizeof(Int), ..., sizeof(DateTime)) = 8
[FieldOffset(8)]
public object Obj;
[FieldOffset(8)]
public string Str;
[FieldOffset(8)]
public string[] Strings;
}
your pure structures (structures that only consist of other structures, i.e. a Tuple<string, int> isn't a pure structure) must be grouped at one offset, and your objects must grouped at another.
|
So using the C# equivalent of a union would over all prevent me from defining the different type variables and using only one, is that the gist of this?
Quote:
Originally Posted by pro4never
Flat file and efficiency never really go in hand but assuming you're doing a flatfile for that specific character then you could always just do a tostring overload to return the flatfile contents for that character instance and then write it to a file.
It's not what you're looking for but it would be pretty damn simple and easy to understand.
|
Ya i know its not very efficient but neither is installing stuff on ever computer I use in order to debug.
|
|
|
07/05/2013, 03:10
|
#11
|
elite*gold: 20
Join Date: Jan 2008
Posts: 2,012
Received Thanks: 2,882
|
yes, a union that contains a series of pure structures, as well as an object has a
maximum size of: max(sizeof(T1), ..., sizeof(Tn)) + sizeof(IntPtr)
where T1, ..., Tn are your pure-structure types.
where as, if it wasn't declared as a union, your structure would have a size of
sum(sizeof(T1), ..., sizeof(Tn)) + sizeof(IntPtr) * nObjectTypes
|
|
|
|
Similar Threads
|
const variables VS enumerators
09/24/2011 - CO2 Private Server - 8 Replies
What is better to use?
It's Conquer Related, because it's for my source.
Currently I have been using enumerators, except for packetids and mapids they are const variables.
|
Effects and Variables help
05/03/2011 - SRO Coding Corner - 0 Replies
Hello EPVP
I need your help of Srevolution source
I would like to know how I declare the variables tied silkroad like quest_complete
quest_getreward
Also And how am I start do all effects.
|
Question about variables
10/05/2008 - CO2 Private Server - 2 Replies
ok you know how u got things like blah.blah, example: mychar.level
so if you were to make variables for all those example: Clevel = mychar.level
what kind of advantages would i gain from this if any?
i rem when i learned visual basic was always told to put every thing in variables
so was just curious if that would b a good way to go
|
Rohan Ingame Variables
08/11/2008 - Rohan - 3 Replies
In order to make a good bot, i need to have and control the Rohan Game Variables, if we can get them, such hp/mp if mob is targeted or not, the position i think i can do a nice bot...but the problem remains how to find this data....
Any idea?
|
All times are GMT +2. The time now is 05:12.
|
|