I want to practice code with DRY principle, but my method uses 2 different classes, classOneDTO and classTwoDTO.. They have different properties and I want to linked it with PRIMARYIDENTIFIER prop with both have the same..
How can I create a generic method to get the property that I want to query with Linq.
Updated: my purpose is to have a generic method that will query the PrimaryIdentifier and get the data to it whether they are using classOneDTO or classTwoDTO. Is there a way to have a single generic method to do this?
private void genericMethod<T>(List<T> workList, GridView grid, int columnNo)
{
if (workList.Any())
{
string CodeString = default;
// Want to dynamic get the properties in different class with PrimaryIDentifier property
// want to check if PrimaryIdentifier is NULL OR EMPTY
var getDataOne = workList.Cast<classOneDTO>().FirstOrDefault(x => !string.IsNullOrEmpty(x.PrimaryIdentifier));
// causing error because of the CAST if wrong type request
var getDataTwo = workList.Cast<classTwoDTO>().FirstOrDefault(x => !string.IsNullOrEmpty(x.PrimaryIdentifier));
if (getDataOne != null || getDataTwo != null)
{
CodeString = (getDataOne != null) ? getDataOne.PrimaryIdentifier : getDataTwo.PrimaryIdentifier;
}
}
}
public class classOneDTO
{
public int PatientID { get; set; }
public string PrimaryIdentifier { get; set; }
public string FirstName{ get; set; }
// so oonnn...
}
public class classTwoDTO
{
public int EntryID { get; set; }
public string PrimaryIdentifier { get; set; }
public string Location{ get; set; }
// so oonnn...
}
CodePudding user response:
All that you need is to make both your classes implement the same interface, i.e. IDTO
:
public interface IDTO
{
string PrimaryIdentifier { get; set; }
}
Then you can tell the compiler to accept only types that implement your new interface:
private void GenericMethod<DTO>(List<DTO> workList, GridView grid, int columnNo)
where DTO: IDTO
{
if (workList.Any())
{
string CodeString = default;
var getData = workList.FirstOrDefault(x => !string.IsNullOrEmpty(x.PrimaryIdentifier));
if (getData != null)
{
CodeString = getData?.PrimaryIdentifier;
}
}
}
(Pay attention to the 2nd row) Additionally, I also made minor adjustments to your class and method namings based on standard .Net naming convention.
Here's the full code:
public class Client
{
private void GenericMethod<DTO>(List<DTO> workList, GridView grid, int columnNo)
where DTO: IDTO
{
if (workList.Any())
{
string CodeString = default;
var getData = workList.FirstOrDefault(x => !string.IsNullOrEmpty(x.PrimaryIdentifier));
if (getData != null)
{
CodeString = getData?.PrimaryIdentifier;
}
}
}
}
public class ClassOneDTO : IDTO
{
public int PatientID { get; set; }
public string PrimaryIdentifier { get; set; }
public string FirstName { get; set; }
// so oonnn...
}
public class ClassTwoDTO : IDTO
{
public int EntryID { get; set; }
public string PrimaryIdentifier { get; set; }
public string Location { get; set; }
// so oonnn...
}
public interface IDTO
{
string PrimaryIdentifier { get; set; }
}
EDIT: as Johnathan Barclay correctly pointed out, there's actually no need to have a generic method if you don't need some more advanced logic there that you didn't show in your example.
private void GenericMethod(IEnumerable<IDTO> workList, GridView grid, int columnNo)
{
if (workList.Any())
{
string CodeString = default;
var getData = workList.FirstOrDefault(x => !string.IsNullOrEmpty(x.PrimaryIdentifier));
if (getData != null)
{
CodeString = getData?.PrimaryIdentifier;
}
}
}