我如何在继承链中多次实现该接口的同时显式实现该接口?
How can i explicitly implement an interface while having implemented that interface multiple times in inheritance chain?
在我的 Unity C# 项目中,我有这些接口:
interface IGameService
{
void Initialize(params object[] args);
}
interface IADManager : IGameService
{
void Show();
}
interface IIAPManager : IGameService
{
void Purchase();
}
还有一个class:
public class MonatizationManager : IAPManager, IADManager
{
...
}
我有一个 IGameService classes 列表,我需要对其进行初始化(我也在使用 Zenject)。例如:
// this basicly means that _iapSettingsProvider and _adSettingsProvider will contain link to a class that implements IADManager and IIAPManager interfaces. In my case this is the same class for these two interfaces - MonatizationManager
[Inject] private readonly ISomeSettingsProvider1 _someSettingsProvider1; // example
...
[Inject] private readonly IADManager _iapSettingsProvider;
[Inject] private readonly IIAPManager _adSettingsProvider;
...
[Inject] private readonly ISomeSettingsProvider2 _someSettingsProvider2; // example
// here i initialize my classes (some are managers, some are just providing game settings etc)
// all initQueue's elements must implement IGameService interface
var initQueue = new GameTaskQueue();
initQueue.Add(new GameTaskInitService(_someSettingsProvider1)); // example
...
initQueue.Add(new GameTaskInitService(_iapSettingsProvider));
initQueue.Add(new GameTaskInitService(_adSettingsProvider));
...
initQueue.Add(new GameTaskInitService(_someSettingsProvider2)); // example
// here my queue is starting to initialize my IGameService classes (basically just calling Initialize() method for each element in the queue)
initQueue.Start();
问题来了:
我对 IADManager 和 IIAPManager 有相同的 class (MonatizationManager),同时我还需要分别初始化这些接口。那么,MonatizationManager class 会是什么样子?
首先,我试过:
// it did not work
public class MonatizationManager : IAPManager, IADManager
{
IGameService.IADManager.Initialize(params object[] args) {...}
IGameService.IIAPManager.Initialize(params object[] args) {...}
}
然后我试了(也没用):
interface IADManager : IGameService
{
new void Initialize(params object[] args);
void Show();
}
interface IIAPManager : IGameService
{
new void Initialize(params object[] args);
void Purchase();
}
public class MonatizationManager : IAPManager, IADManager
{
void IIAPManager.Initialize(params object[] args)
{
...
}
void IADManager.Initialize(params object[] args)
{
...
}
// compiler wants me to also write this method, but i think i don't need it
public void Initialize(params object[] args)
{
...
}
}
是否可以在我的 MonatizationManager class 中为这两个接口(IIAPManager 和 IADManager)显式实现 Initialize(params object[] args) 方法?
你的设计有点过于复杂了。您应该只实现一个 Intialize
方法,而不是两个。如果客户使用您的 class 并且不得不调用 Initialize
两次,这将非常令人困惑。然而,单个实现当然可以做任何你想做的事,例如调用两个私有方法
此外,您的 manager-class 已经 是 一个 IADManager
,因此没有理由也拥有该类型的成员并通过调用它来使用该成员成员(除非你实施 decorator-pattern 或类似的)。
所以我建议改用这个:
interface IGameService
{
void Initialize(params object[] args);
}
interface IADManager : IGameService
{
void Show();
}
interface IIAPManager : IGameService
{
void Purchase();
}
public class MonatizationManager : IAPManager, IADManager
{
void Initialize(params object[] args)
{
// code for initializing the one interface
// code for initializing the other interface
}
void Show() { ... }
void Purchase() { ... }
}
顺便说一句,您通常会初始化特定的 classes,而不是 接口 。虽然每个 class 都有一些 initialize-method 并不一定意味着这样的初始化应该在 public 接口上可用。具有这样的设计将允许多次调用 Initialize
,例如,这通常不是预期的。相反,你应该在 constructor-code 中提供一个完全可用的 class(除非发生了一些重大的魔法,在这种情况下你会实现一些 lazy-loading)。然后你的 client-code 不需要知道它是否已经初始化了 class,因为它已经得到一个完全初始化的
在我的 Unity C# 项目中,我有这些接口:
interface IGameService
{
void Initialize(params object[] args);
}
interface IADManager : IGameService
{
void Show();
}
interface IIAPManager : IGameService
{
void Purchase();
}
还有一个class:
public class MonatizationManager : IAPManager, IADManager
{
...
}
我有一个 IGameService classes 列表,我需要对其进行初始化(我也在使用 Zenject)。例如:
// this basicly means that _iapSettingsProvider and _adSettingsProvider will contain link to a class that implements IADManager and IIAPManager interfaces. In my case this is the same class for these two interfaces - MonatizationManager
[Inject] private readonly ISomeSettingsProvider1 _someSettingsProvider1; // example
...
[Inject] private readonly IADManager _iapSettingsProvider;
[Inject] private readonly IIAPManager _adSettingsProvider;
...
[Inject] private readonly ISomeSettingsProvider2 _someSettingsProvider2; // example
// here i initialize my classes (some are managers, some are just providing game settings etc)
// all initQueue's elements must implement IGameService interface
var initQueue = new GameTaskQueue();
initQueue.Add(new GameTaskInitService(_someSettingsProvider1)); // example
...
initQueue.Add(new GameTaskInitService(_iapSettingsProvider));
initQueue.Add(new GameTaskInitService(_adSettingsProvider));
...
initQueue.Add(new GameTaskInitService(_someSettingsProvider2)); // example
// here my queue is starting to initialize my IGameService classes (basically just calling Initialize() method for each element in the queue)
initQueue.Start();
问题来了: 我对 IADManager 和 IIAPManager 有相同的 class (MonatizationManager),同时我还需要分别初始化这些接口。那么,MonatizationManager class 会是什么样子?
首先,我试过:
// it did not work
public class MonatizationManager : IAPManager, IADManager
{
IGameService.IADManager.Initialize(params object[] args) {...}
IGameService.IIAPManager.Initialize(params object[] args) {...}
}
然后我试了(也没用):
interface IADManager : IGameService
{
new void Initialize(params object[] args);
void Show();
}
interface IIAPManager : IGameService
{
new void Initialize(params object[] args);
void Purchase();
}
public class MonatizationManager : IAPManager, IADManager
{
void IIAPManager.Initialize(params object[] args)
{
...
}
void IADManager.Initialize(params object[] args)
{
...
}
// compiler wants me to also write this method, but i think i don't need it
public void Initialize(params object[] args)
{
...
}
}
是否可以在我的 MonatizationManager class 中为这两个接口(IIAPManager 和 IADManager)显式实现 Initialize(params object[] args) 方法?
你的设计有点过于复杂了。您应该只实现一个 Intialize
方法,而不是两个。如果客户使用您的 class 并且不得不调用 Initialize
两次,这将非常令人困惑。然而,单个实现当然可以做任何你想做的事,例如调用两个私有方法
此外,您的 manager-class 已经 是 一个 IADManager
,因此没有理由也拥有该类型的成员并通过调用它来使用该成员成员(除非你实施 decorator-pattern 或类似的)。
所以我建议改用这个:
interface IGameService
{
void Initialize(params object[] args);
}
interface IADManager : IGameService
{
void Show();
}
interface IIAPManager : IGameService
{
void Purchase();
}
public class MonatizationManager : IAPManager, IADManager
{
void Initialize(params object[] args)
{
// code for initializing the one interface
// code for initializing the other interface
}
void Show() { ... }
void Purchase() { ... }
}
顺便说一句,您通常会初始化特定的 classes,而不是 接口 。虽然每个 class 都有一些 initialize-method 并不一定意味着这样的初始化应该在 public 接口上可用。具有这样的设计将允许多次调用 Initialize
,例如,这通常不是预期的。相反,你应该在 constructor-code 中提供一个完全可用的 class(除非发生了一些重大的魔法,在这种情况下你会实现一些 lazy-loading)。然后你的 client-code 不需要知道它是否已经初始化了 class,因为它已经得到一个完全初始化的