所以我正在撰寫一個 C# System.Commandline 應用程式,我注意到我的方法都遵循類似的結構 - 每個 Handler 類都有一個公共方法 RunHandlerAndReturnExitCode,采用一組不同的選項,我已經將這些選項封裝到一個類作為引數傳遞。像下面這樣:
public class FirstHandler
{
public int RunHandlerAndReturnExitCode(FirstOptions options) { }
}
public class SecondHandler
{
public int RunHandlerAndReturnExitCode(SecondOptions options) { }
}
等等。我嘗試創建一個 OptionsBase 抽象類,并讓我的其他 Options 類繼承它,然后創建了一個如下所示的處理程式介面:
internal interface IHandler
{
int RunHandlerAndReturnExitCode<T>(T options) where T : OptionsBase;
}
處理程式看起來像:
public class FirstHandler : IHandler
{
public int RunHandlerAndReturnExitCode<FirstOptions>(FirstOptions options) { }
}
編輯:我還有從 OptionsBase 繼承的 Options 類:
public class FirstOptions : OptionsBase
{
public string FirstProperty { get; set; }
}
和 OptionsBase 類:
public abstract class OptionsBase { }
但這會回傳錯誤“型別引數 'FirstOptions' 的約束必須與型別引數 T 的約束匹配。(請考慮使用顯式介面實作)。
我哪里錯了?這甚至是正確的方法嗎?
uj5u.com熱心網友回復:
根據您嘗試執行的操作,您可以按照以下方式進行操作。
介面應該在其上設定通用型別,即。IHandler<T> where T : OptionsBase,然后具有的單獨的實施方式FirstHandler和SecondHandler。
public class OptionsBase
{
}
public class FirstOptions : OptionsBase
{
}
public class SecondOptions : OptionsBase
{
}
internal interface IHandler<T> where T : OptionsBase
{
int RunHandlerAndReturnExitCode(T options);
}
public class FirstHandler : IHandler<FirstOptions>
{
public int RunHandlerAndReturnExitCode(FirstOptions options)
{
throw new NotImplementedException();
}
}
public class SecondHandler : IHandler<SecondOptions>
{
public int RunHandlerAndReturnExitCode(SecondOptions options)
{
throw new NotImplementedException();
}
}
這使您能夠單獨測驗每個處理程式,引入一個基本抽象類,并使用 DependencyInjection 作為選項:像下面的例子:
public abstract class AbstracHandler<T> : IHandler<T> where T : OptionsBase
{
protected readonly T _options;
public AbstracHandler(T options)
{
_options = options;
}
public abstract int RunHandlerAndReturnExitCode(T options);
}
public class FirstHandler : AbstracHandler<FirstOptions>
{
public FirstHandler(FirstOptions options) : base(options)
{
}
public override int RunHandlerAndReturnExitCode(FirstOptions options)
{
throw new NotImplementedException();
}
}
uj5u.com熱心網友回復:
您正在函式級別設定抽象和約束,這意味著實作該介面的任何類都將實作帶有約束的抽象方法。
public class Program
{
public static void Main()
{
new FirstHandler().RunHandlerAndReturnExitCode(new FirstOptions
{
FirstProperty = "FirstOptionProp",
SomeBaseOptionOne = 1,
SomeBaseOptionTwo = 2,
}); ;
}
}
public abstract class OptionsBase
{
public int SomeBaseOptionOne { get; set; }
public int SomeBaseOptionTwo { get; set; }
}
public class FirstOptions : OptionsBase
{
public string FirstProperty { get; set; }
}
internal interface IHandler<T>
where T : OptionsBase
{
int RunHandlerAndReturnExitCode(T options);
}
public class FirstHandler : IHandler<FirstOptions>
{
public int RunHandlerAndReturnExitCode(FirstOptions options)
{
return options.SomeBaseOptionTwo;
}
}
您可以在服務中將其注冊為:
services.AddScoped(typeof(IHandler<>), typeof(FirstHandler<>))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/383546.html
