jeudi 30 novembre 2017

Can I use reflection to instantiate properties that inherit from a generic type? (C#)

I was wondering if there was a tidy way to use reflection to instantiate a bunch of properties in a class, with a constraint that the property types to instantiate should only inherit from certain classes, and what if one of these classes has a generic type parameter.

For example.....

public class Control
{
    public string Name => "Test Name";
}

public abstract class BasePage<T> { }

public class HomePage : BasePage<HomePage> { }

public class LoginPage : BasePage<LoginPage>
{
    public Control Test { get; set; } = new Control();
}

public class LoginLinkPage : BasePage<LoginLinkPage>
{
    public Control Test { get; set; } = new Control();
}

public class UserPage : HomePage
{
    public Control Test { get; set; } = new Control();
}

public class Pages
{
    public UserPage UPage { get; set; }
    public LoginPage LPage { get; set; }
    public LoginLinkPage LLPage { get; set; }
} 

Is it possible to instantiate all the properties in Pages in a single method? And allow for more properties to be added and instantiated assuming they inherit from either BasePage<T> or HomePage?

This is what I have so far, but it only checks the subclass of the property type is homepage...

class Program
{
    public static void InitializeControls<T>(T page)
    {
        var pageType = typeof(T);

        var properties = pageType.GetProperties().Where(p => p.PropertyType.IsSubclassOf(typeof(HomePage)));

        foreach (var property in properties)
        {
            property.SetValue(page, Activator.CreateInstance(property.PropertyType));
        }
    }

    static void Main(string[] args)
    {
        var pages = new Pages();

        InitializeControls(pages);

        Console.WriteLine(pages.UPage.Test.Name); // "Test Name"
        Console.WriteLine(pages.LLPage.Test.Name); // NullReferenceException
        Console.WriteLine(pages.LPage.Test.Name);  // NullReferenceException       

        Console.ReadLine();
    }
}

I can't wrap my head around whether it's possible to also do a check for BasePage<T>, if T could be various different types.

I would be open to design changes that might solve this problem.

Thanks,





Aucun commentaire:

Enregistrer un commentaire