I have the following interface which contains a static method definition:
public interface IUpgradableDataSource { static abstract Task<JsonElement> UpgradeSourceConfigurationAsync( JsonElement configuration, CancellationToken cancellationToken ); } This interface is implemented by dynamically loaded plugins. To invoke UpgradeSourceConfigurationAsync on them, I need to use reflection which I would like to avoid (dataSourceType is the plugin's type):
var dataSourceType = <the System.Type of the plugin> var dataSourceInterfaceTypes = dataSourceType.GetInterfaces(); if (dataSourceInterfaceTypes.Any(x => x == typeof(IUpgradableDataSource))) { var methodInfo = dataSourceType .GetMethod( nameof(IUpgradableDataSource.UpgradeSourceConfigurationAsync), BindingFlags.Public | BindingFlags.Static )!; var upgradedConfiguration = await (Task<JsonElement>)methodInfo.Invoke( default, [ configuration, cancellationToken ] )!; // ... } else { // ... } I am implementing exactly the same code also in Python where I can solve this problem quite elegant:
if issubclass(data_source_type, IUpgradableDataSource): upgraded_configuration = await data_source_type.upgrade_source_configuration(configuration) ... else ... By simply using issubclass I get proper intellisense support and pyright is also happy:
My question is: Is there something similar in C#? I.e. can I just check if the System.Type instance is deriving from IUpgradableDataSource and then invoke static methods defined on that type?
I tried the following but it does not work (compile-time error):
var myCastedType = dataSourceType as IUpgradableDataSource; await myCastedType.UpgradeSourceConfigurationAsync(...) 
asto work with it. You should work with concrete instance, not an instance of theSystem.Type. Without seeing full code it is hard to tell what you need to do, but in some cases you can useActivator.CreateInstance:var castedInstance = Activator.CreateInstance(dataSourceType) as IUpgradableDataSource; if(castedInstance is not null) ...