CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Aug 2009
    Posts
    6

    Question 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);
    ..
    }

  2. #2
    Join Date
    Jul 2006
    Posts
    297

    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.

  3. #3
    Join Date
    May 2007
    Posts
    1,546

    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.

  4. #4
    Join Date
    Aug 2009
    Posts
    6

    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

  5. #5
    Join Date
    Aug 2009
    Posts
    6

    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

  6. #6
    Join Date
    Aug 2009
    Posts
    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()));
    }
    }
    }

  7. #7
    Join Date
    Jul 2006
    Posts
    297

    Re: Generic class instance casting to generic class type

    Quote Originally Posted by SiegfriedN View Post
    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.

  8. #8
    Join Date
    Aug 2009
    Posts
    6

    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()));
    }
    }
    }

  9. #9
    Join Date
    Aug 2009
    Posts
    6

    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

  10. #10
    Join Date
    Jul 2006
    Posts
    297

    Re: Generic class instance casting to generic class type

    Quote Originally Posted by SiegfriedN View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured