0

Im sorry for my bad english. There is a problem that I cannot solve because I am new to generics.

When the constructor method is running, How can I detect the incoming class. I have to continue the process by accessing the class properties. Can you help me about the way I should follow?

 public class IslemeBasla<T> where T : class, IEntity
{
        private string _profilName;
        public int _processCount;
        private IWebDriver _driver;
        private ChromeDriverService _cService;
        private string _arguments;


        public T _hEntity;



        public IslemeBasla()
        {
            Type type = typeof(T);

            switch (type.Name)
            {
                // I want to do something like this.
                case "Facebook": _hEntity = (facebook)T;
                    
                    break;
                case "Twitter":
                    break;
                case "Youtube":
                    break;
                case "Instagram":
                    break;
                default:
                    break;
            }
        }
    }

Update ; All classes have the same characteristics. they inherit from a single class. but some classes have their own characteristics.

The method I have created for this is as follows. It's a not good example, but that's how I came to the solution.

 public class IslemeBasla<T> where T : class, IEntity
{
        private Facebook _fbHesap;
        private Youtube _ytHesap;
        private Instagram _insHesap;
        private Twitter _twHesap;


        public T _hEntity;
        private string _browserLoc;


        public void SetConfigs()
        {
            Type type = typeof(T);

            switch (type.Name)
            {
                _fbHesap = _hEntity as Facebook;
                _browserLoc = _fbHesap.Mail;                    
                    break;
                case "Twitter":  _twHesap = _hEntity as Twitter;
                _browserLoc = _twHesap.Mail;  
                    break;
                case "Youtube": _ytHesap = _hEntity as Youtube;
                    _browserLoc = _ytHesap.Mail;  
                    break;
                case "Instagram": _insHesap = _hEntity as Instagram;
                    _browserLoc = _insHesap .Mail;  
                    break;
                default:
                    break;
            }
        }
    }
bemonth
  • 1
  • 2
  • It sounds like you should be using a discriminated-union instead of generics. – Dai Mar 26 '21 at 11:31
  • 4
    This is a code smell, you shouldn't need to be doing this. Why would your class care about the generic type? – DavidG Mar 26 '21 at 11:34
  • 2
    I totally agree with DavidG. Generics are there to do the same stuff on different kind of objects. If you need to distinguish them, you're using it wrong. – Thomas Weller Mar 26 '21 at 11:37
  • If all of these objects share the same property names then create a base class for them to inherit. Then use that base type as your constraint on T and you will have access to those properties regardless of the actual type. If they do not, you should use a different class to handle each so you can instantiate it through dependency injection or a factory and pass your type to it. – Steve Harris Mar 26 '21 at 11:40
  • I agree with what you say. I have to study this issue a little bit. I will share the method I used to circumvent this problem. – bemonth Mar 27 '21 at 12:13

1 Answers1

0

This is not the way to use generics. In the example provided you could just as well just use a regular reference, you can then use pattern matching to handle different implementations and use the object however you wish.

Your example does not show what kind of object you have, or how you intend to use them. So I will pretend they are classes to post messages to some sort of social media platform.

public IEntity _hEntity;
public PostMessage()
{
    switch (_hEntity)
    {
         case FaceBook fb: 
                fb.PostMessage("hello World"); // Do something with the object
            break;
         case Instagram ig: 
                ig.PostMessage("hello World");
         break;
         default:
            throw new NotImplementedException();
    }
 }

However, a better alternative would be to put the logic in the classes themselves and have an appropriate interface method. This will require that each class can accept the same parameters to do whatever it needs to do:

public interface ISocialMedia{
    public void Post(string message);
}
...
public ISocialMedia socialMedia;
public PostMessage()
{
     socialMedia.Post("Hello World");
}

Another option (as dai mentions in a comment) that might be appropriate is a discriminated union. This can be useful if you want a single value that can be of several different unrelated types. For example you could either have a hammer or a banana.

JonasH
  • 28,608
  • 2
  • 10
  • 23