-1

Im working on creating a method for logging data. I've repeated the same content multiple times, the only thing thats different is the type of object I'm using. (they both have the exact same properties. see code below:

    public void LogContentLinkInformation() // here i would like the choice to pass in either a object type of "Product" or "Category"
    {
        for (int i = 0; i < categoryToUpdate?.CategoryImages?.Items.Count; i++)
        {
            _logger.LogDebug(nameof(ProcessFiles), $"Content Link Id: {categoryToUpdate?.CategoryImages?.Items[i].ContentLink.ID.ToString()}");
            _logger.LogDebug(nameof(ProcessFiles), $"Provider Name: {categoryToUpdate?.CategoryImages?.Items[i].ContentLink.ProviderName}");
            _logger.LogDebug(nameof(ProcessFiles), $"GetPublishedOrLatest: {categoryToUpdate?.CategoryImages?.Items[i].ContentLink.GetPublishedOrLatest.ToString()}");

        }
    }

As mentioned they both have the same properties, so to get the ContentlinkID, provider name and GetPublishedorLatest would all follow the same path for both the product and category object.

Any help would be appreciated.

Thanks

S92
  • 7
  • 4
  • 8
    "As mentioned they both have the same properties" - do they implement a common interface? – Mathias R. Jessen Jul 17 '23 at 19:16
  • hi @MathiasR.Jessen they both have the same properties but are inherited from two different base classes. – S92 Jul 17 '23 at 21:19
  • You can possibly use something like this: https://stackoverflow.com/questions/9664912/c-sharp-passing-a-generic-object – gaurav Jul 18 '23 at 04:09

1 Answers1

0

There are a few options

Overload ToString()

Let both your objects overload the ToString method and write out anything that is useful to log. This assumes you are not using this for anything else, and the amount of information makes sense for logging. I.e. great for something like a Angle-type, but probably less useful for larger objects.

Use a common interface

Add the properties used to a interface and have each type implement this interface. That the types have different base classes is immaterial, while a type can only have one base class, it can implement multiple interfaces just fine.

public void MyLogMethod(IMyInterface obj){
    // do logging
}

Delegate conversion to properties

In some cases delegates can be used to let the caller specify what properties should be used:

public void MyLogMethod<T>(T obj, params Func<T, string>[] properties)
{
    foreach (var myDelegate in delegates)
    {
       var s = myDelegate(obj);
    }
}

Use reflection

You can use reflection to get the property values

public void MyLogMethod<T>(T obj, params Func<T, string>[] properties)
{
    var t = obj.GetType();
    foreach (var prop in t.GetProperties())
    {
        // Optionally check for if property name matches some predefined list
        var propertyValue = prop.GetValue(obj, null)?.ToString();
    }
}

But there are major downsides with reflection. It is usually quite slow, certainly a concern for logging. And it can also be fragile, if the types are changed the logging might also unexpectedly change or break.

JonasH
  • 28,608
  • 2
  • 10
  • 23