Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Property of generic member in generic class [duplicate]

Tags:

c#

generics

I am newbie in C#. I am trying to create a Generic class. I have three classes and a Main/Generic class.

Three Classes

public class A
{
    public string Name { get; set; }
    public string Address { get; set; }

    public A(string _name, string _address)
    {
        Name = _name;
        Address = _address;
    }        
}

public class B
{
    public string Name { get; set; }
    public string Address { get; set; }

    public B(string _name, string _address)
    {
        Name = _name;
        Address = _address;
    }
}

public class C
{
    public string Name { get; set; }
    public string Address { get; set; }

    public C(string _name, string _address)
    {
        Name = _name;
        Address = _address;
    }
}

Generic Class

public class GenericClass<T>
{
    public GenericClass(T obj)
    {
        DynamicObject = obj;
    }

    public T DynamicObject { get; set; }

}

I have successfully created a Generic class.

class Program
{
    static void Main(string[] args)
    {
        A objA = new A("Mohit", "India");
        GenericClass<A> objGenericClass = new GenericClass<A>(objA);

        Console.ReadLine();
    }

}

Now, if I need to use Class A/B/C property in the Generic class. How can I use it? I know that class reference type decide on the runtime. So, I can't use it in below way.But, Is there any other way?

public class GenericClass<T>
{
    public GenericClass(T obj)
    {
        DynamicObject = obj;
    }

    public T DynamicObject { get; set; }


    public void UseClassPro()
    {
        Console.WriteLine("Address " + DynamicObject.Address);//Compile time error here.
    }

}
like image 423
KiddoDeveloper Avatar asked Dec 19 '22 10:12

KiddoDeveloper


2 Answers

The Other Answers are right, but...

I just want to point out: while those other answers promote valid C# code, they make the generic aspect of you implementation superflous. You don't need generics anymore:

Given a base class or interface like

public interface IHasAddress
{
    string Address { get; }
}

you don't need a Generic class anymore for what you are trying to achive (from what i can tell by the code you provided):

public class NotSoGenericClass
{
    public GenericClass(IHasAddress obj)
    {
        DynamicObject = obj;
    }

    public IHasAddress DynamicObject { get; set; }    
}

So as you can see, you can easily implement the desired behaviour w/o generics.

For you as a Beginner, i'd recommend the following basic rules when it comes to generics:

  1. When you think you have to use generics, force yourself to consider abstraction via interfaces, abstract classes or base classes first. This often leads to simpler and cleaner solutions.
  2. Same goes with Reflection. When you think you need Reflection, consider generics (Rule 1 is valid at that point to)

But Nothings wrong with Generics, its just more complex and often not needed. Compare the class above with the generic solution:

public class GenericClass<T> where T : IHasAddress  // just for the sake of generics
{
    public GenericClass(T obj)
    {
        DynamicObject = obj;
    }

    public T DynamicObject { get; set; }    
}

Looks more complex and doesn't add any benefit, does it? Also note that you need a Interface/baseclass no matter what. Otherwise, you could also use Reflection (not recommended).

To actually answer your question

The precise answer to your question is:

You have to define that you generic parameter has to be assignable to IHasAddress using

public class GenericClass<T> where T : IHasAddress
                             ^^^^^^^^^^^^^^^^^^^^^
                                  This Part

This way, the compiler knows that T inherits or is of type IHasAddress or what ever you define. You can also pass multiple types at this place which adds mor flexibility when it comes to designing your interfaces.

Maybe, there are points to consider in your usecase which are not obvious from the information you provided in the question. In that case, feel free to add some details and i'll be happy to deep dive into those as well.

like image 145
nozzleman Avatar answered Dec 24 '22 01:12

nozzleman


define interface:

public interface IABC
{
    string Name { get; set; }
    string Address { get; set; }
}

and in your generic class definition specify this interface:

public class GenericClass<T> where T: IABC
{
    public GenericClass(T obj)
    {
        DynamicObject = obj;
    }

    public IABC DynamicObject { get; set; }    
}

All your 3 classes implemet this interface:

public class A : IABC
public class B : IABC
public class C : IABC

After that you could call properties of IABC

A objA = new A("Mohit", "India");
GenericClass<A> objGenericClass = new GenericClass<A>(objA);
var adress = objGenericClass.DynamicObject.Address;
like image 33
Maksim Simkin Avatar answered Dec 24 '22 03:12

Maksim Simkin