Roxy'Pro
Roxy'Pro

Reputation: 4444

How to make C# method generic so it could be used by different classes

How could I make this method more like a generic - that can be used by different classes

Here is my method which should be used now by two classes, since now it was invoked only in one place and input param was IdentDto, and now I should use it on one more place where I should pass as param class User.

Here's method definition:

private IdentificationResponse Identification (IdentDto request)
{
    var customRequestion = new CustomRequest
    {
        FirstADDRESS = request.Company.Address.FirstAddress,
        SecondADDRESS = request.Company.Address.SecondAddress,
        CompanyTown = request.Company.Address.City,
    };

    if (request.Company.HasUserAdded)
    {
        customRequestion.Name = request.User.Name;
        customRequestion.Surname = request.User.Surname;
    }

    return null; // Not important for this case
}

IdentDto contains UserDto which contains User inside and it looks like this:

public class IdentDto
{
    public UserDto User { get; set; }
    public CompanyDto Company { get; set; }
}

This works fine when this method is used by IdentDto, but since User contains Company prop in himself, sometimes it would be awesome to be able to receive User also as a parameter and User's class looks like this:

public class User 
{
    public string Name { get; set; }

    public string SurName { get; set; }

    public Company Company { get; set; }
}

And If I change a parameter to User instead of IdentDto than I could access directly to Name and Surname so code might look like this:

private IdentificationResponse Identification (IdentDto request)
{
    var customRequestion = new CustomRequest
    {
        FirstADDRESS = request.Company.Address.Address1,
        SecondADDRESS = request.Company.Address.Address2,
        CompanyTown = request.Company.Address.City,
    };

    if (request.Company.HasUserAdded)
    {
        customRequestion.Name = request.Name; // Here I would get issue cuz it's not anymore request.User.Name;
        customRequestion.Surname = request.Surname; // Here I would get only issue cuz it's not anymore request.User.Surname; now it become request.Surname because I would use User class for example..
    }

    return null; // Not important for this case
}

So as you can see If I could pass user than I could access directly to that params, but that's no solution because I can not change it likes that because some else, for example, needs to send IdentDto as param...

So I'm wondering how could I redefine this method so the method could work with different classes at the same time.

Thanks a lot!

Cheers!

Upvotes: 0

Views: 107

Answers (2)

Robert McKee
Robert McKee

Reputation: 21477

The simple way:

private IdentificationResponse Identification(Company company, string Name, string Surname)
{
 ... Your old logic here ...
}

private IdentificationResponse Identification(IdentDto req) => 
  Identification(req.Company, req.User.Name, req.User.Surname)

private IdentificationResponse Identification(User req) => 
  Identification(req.Company, req.Name, req.SurName)

The adapter (via extensions) way:

public static class UserExtensions
{
  public static IdentDto ToIdentDto(this User u)
  {
    return new IdentDto
    {
      User = new UserDto {Name = u.Name, SurName = u.SurName},
      Company = u.Company.ToCompanyDto()
    }
  }
}
public static class CompanyExtensions
{
  public static CompanyDto ToCompanyDto(this Company c)
  {
    ...
  }
}

Then you can call your method via var i = Identification(user.ToUserDto());

The implicit type conversion way:

public class User 
{
  public string Name { get; set; }
  public string SurName { get; set; }
  public Company Company { get; set; }
  public static implicit operator IdentDto(User u) =>new IdentDto
        {
          User = new UserDto {Name = u.Name, SurName = u.SurName},
          Company = new CompanyDto { ... }
        };
}

Or lastly, you can refactor into common interfaces (which is the most organized way to do it).

Upvotes: 0

dcg
dcg

Reputation: 4219

You could make IdentDto and User to implement an interface, let's say:

public interface IMyInterface {

  public Company Company { get; }
  public string Name { get; }
  public string SurName { get; }
}

public class IdentDto : IMyInterface {
    public string Name { get => User.Name; }
    public string SurName { gt => User.SurName; }
}

public class User: IMyInterface { }

And then pass to your method a reference to the interface instead of a specific type. Hope it helps.

Upvotes: 1

Related Questions