-
August 10th, 2009, 10:30 AM
#1
Generic class instance casting to generic class type
Hi,
I am a newbie to c# and have the following problem to do with generic type casting to use 'generically' see '***' below
Probably best to explain this one with some simple code..
...
class GenericClass<T> //Generic class.
{
public AddValues<T> (int x, int y) : int
{
return x + y;
}
}
class UseClass //Class that uses the GenericClass
{
public DoSomething(object o_classinstance) : int
{
... *** The code below works, but is not neat. How can I eliminate the duplication?
if (o_classinstance.GetType() == typeof(GenericClass<int>))
{
GenericClass<int> o_localclassint = (GenericClass<int>)o_classinstance; //cast
return o_localclassint.AddValues(1, 2);
}
else if (o_classinstance.GetType() == typeof(GenericClass<string>))
{
GenericClass<string> o_localclassstring = GenericClass<string>)o_classinstance; //cast
return o_localclassint.AddValues(3, 4); // <- messy duplication..
}
}
}
....
... in program ...
....
{
..
GenericClass<int> o_intclass = new GenericClass<int>();
GenericClass<string> o_stringclass = new GenericClass<string>();
o_useclass = new UseClass();
int z = o_useclass.DoSomething(o_intclass);
int i = o_useclass.DoSomething(o_stringclass);
..
}
-
August 10th, 2009, 11:39 AM
#2
Re: Generic class instance casting to generic class type
Welcome to the forum.
A few things, first of all it easiest if you can wrap your code inside [ code ] [ /code ] tags, it makes it a lot easier to read. Secondly, the code you posted doesn't even compile there were a number of syntax errors I had to correct to get it working. I understand this is just an example, but your code doesn't even need a generic class here because it handles strings and integers the same way. Hopefully I understand what your problem is and this will help you out. If not then try to explain a little more what you're trying to do and i'll do my best to answer your question.
Code:
class GenericClass<T> //Generic class.
{
public int AddValues()
{
if(typeof(T) == typeof(string))
return 7;
else if (typeof(T) == typeof(int))
return 3;
return 0;
}
}
class UseClass //Class that uses the GenericClass
{
public int DoSomething<T>(GenericClass<T> o_classinstance)
{
return o_classinstance.AddValues();
}
}
Again, theres no need for generic classes here so if you can explain what you're trying to do we can probably find a better solution for you that doesn't use generic classes.
-
August 10th, 2009, 01:38 PM
#3
Re: Generic class instance casting to generic class type
If you want to use mathematical operators on generic types, you can't This is by design. The best you can hope for is to create methods like "public T Add (T other)" and " public T Multiply (T other)" and make them abstract so inheriting classes must implement the method body. For example:
Code:
public abstract class Base<T>
{
public Base<T> Value { get; set; }
public abstract Base<T> Add (Base<T> other);
}
public abstract DoubleClass : Base<double>
{
public DoubleClass (double value)
{
Value = value;
}
public override Base<double> Add (Base<double> other)
{
return new DoubleClass (this.Value + other.Value);
}
}
It's not great, but it's the only sane way of doing it 'generically'. Is this really what you want to do?
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
August 10th, 2009, 03:41 PM
#4
Re: Generic class instance casting to generic class type
Thanks for the reply monalin,
This was just a crude as simple as possible example typed on the fly. Sorry about the syntax errors.
To give more info. I am working with the Csla.Net framework. If you are familiar with the Csla.Net framework, I have a derived PropertyInfo<T> class that extended to have some metadata like DisplayText. I am using my PropertyInfo class as property of a Label. This is to get metadata e.g. DisplayText from the property info instance.
The properties types defined in my BO classes can be of any type <T> for PropertyInfo, thus in my Label class to get to the DisplayText on my PropertyInfo class I need to do all the casting and duplicated code as in my example. I hope you understand.
Siegfried
-
August 10th, 2009, 03:46 PM
#5
Re: Generic class instance casting to generic class type
Thanks for your reply Mutant Fruit,
See also my reply to monalin, I do not really have control over the base classes. I was more interested in being able to cast a 'Generic' class instance via a common anscestor.
I have an idea to use a new Interface for my meta data to be implemented my extended class from the Csla PropertyInfo<T>
If it works I will post example code here.
Siegfried
-
August 10th, 2009, 04:02 PM
#6
Re: Generic class instance casting to generic class type
OK, this code compiles. WinForm with button and button click..
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GenericTypesTest
{
class GenericClass<T> //Generic class.
{
public int AddValues<T>(int x, int y)
{
return x + y;
}
}
class UseClass //Class that uses the GenericClass
{
public int DoSomething(object o_classinstance)
{
if (o_classinstance.GetType() == typeof(GenericClass<int>))
{
GenericClass<int> o_localclassint = (GenericClass<int>)o_classinstance; //cast
return o_localclassint.AddValues<int>(1, 2);
}
else if (o_classinstance.GetType() == typeof(GenericClass<string>))
{
GenericClass<string> o_localclassstring = (GenericClass<string>)o_classinstance; //cast
return o_localclassstring.AddValues<string>(3, 4); // <- messy duplication..
}
else
return 0;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
GenericClass<int> o_intclass = new GenericClass<int>();
GenericClass<string> o_stringclass = new GenericClass<string>();
UseClass o_useclass = new UseClass();
int z = o_useclass.DoSomething(o_intclass);
int i = o_useclass.DoSomething(o_stringclass);
MessageBox.Show(string.Format("Value Z: {0} Value y: {1}", z.ToString(), i.ToString()));
}
}
}
-
August 10th, 2009, 04:10 PM
#7
Re: Generic class instance casting to generic class type
Originally Posted by SiegfriedN
Thanks for the reply monalin,
This was just a crude as simple as possible example typed on the fly. Sorry about the syntax errors.
To give more info. I am working with the Csla.Net framework. If you are familiar with the Csla.Net framework, I have a derived PropertyInfo<T> class that extended to have some metadata like DisplayText. I am using my PropertyInfo class as property of a Label. This is to get metadata e.g. DisplayText from the property info instance.
The properties types defined in my BO classes can be of any type <T> for PropertyInfo, thus in my Label class to get to the DisplayText on my PropertyInfo class I need to do all the casting and duplicated code as in my example. I hope you understand.
Siegfried
Maybe i understand now... Maybe this will help? This function takes any object as a parameter and if that object can be converted to type "T" it will be converted. Otherwise it will return its default value.
Code:
public static T ConvertTo<T>(Object obj)
{
try
{
return (T)Convert.ChangeType(obj, typeof(T));
}
catch
{
return default(T);
}
}
for example
Code:
Int32 y = ConvertTo<Int32>("12390");
Int32 x = ConvertTo<Int32>(2094);
Last edited by monalin; August 10th, 2009 at 04:19 PM.
-
August 10th, 2009, 04:17 PM
#8
Re: Generic class instance casting to generic class type
This solves my 'problem'. The code below uses an interface as a common type for the generic classes using the same original example. Again Win form with button and button click.
Thanks for all who helped
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GenericTypesTest
{
interface IAddValuesInterface
{
int AddValues(int x, int y);
}
class GenericClass<T> : IAddValuesInterface //Generic class.
{
public int AddValues(int x, int y)
{
return x + y;
}
}
class UseClass //Class that uses the GenericClass
{
public int DoSomething(IAddValuesInterface o_classinstance, int x, int y)
{
return o_classinstance.AddValues(x, y);
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
GenericClass<int> o_intclass = new GenericClass<int>();
GenericClass<string> o_stringclass = new GenericClass<string>();
UseClass o_useclass = new UseClass();
int z = o_useclass.DoSomething(o_intclass, 1, 2);
int i = o_useclass.DoSomething(o_stringclass, 3, 4);
MessageBox.Show(string.Format("Value Z: {0} Value y: {1}", z.ToString(), i.ToString()));
}
}
}
-
August 10th, 2009, 04:31 PM
#9
Re: Generic class instance casting to generic class type
monalin,
Sorry, this is a bit too advanced for me to understand properly. It looks interesting. Is this a 'custom' convertor to cast the generic classes? The normal convert only works with Sytem types as far as I have found out.
I would be grateful for a small explanation and a simple example of usage.
Thanks,
Siegfried
-
August 10th, 2009, 04:53 PM
#10
Re: Generic class instance casting to generic class type
Originally Posted by SiegfriedN
monalin,
Sorry, this is a bit too advanced for me to understand properly. It looks interesting. Is this a 'custom' convertor to cast the generic classes? The normal convert only works with Sytem types as far as I have found out.
I would be grateful for a small explanation and a simple example of usage.
Thanks,
Siegfried
It only works with system types like you said. The code you provided works but it just seems overkill. I understand what you're trying to do now, i just don't understand why you're trying to do this. The AddValues(int x, int y) function has the same parameters and return value for each type. So essentially your code is the same as this. Because no matter what type you use it only adds the two integers you input and returns the value.
Code:
public int DoSomething(IAddValuesInterface o_classinstance, int x, int y)
{
return x + y;
}
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|