![](/img/trans.png)
[英]Unable to cast a class implementing and interface to this interface in IronPython and C#
[英]Cast a class as implementing interface
我有一個實現兩個接口的類:
public class MyService : IServiceA, IServiceB
接口IServiceA
是完全一樣IServiceB
,但是當MyService
被實例化,因為每個這些接口,一組作為不同的值的MyService
被加載到存儲器的參數:
public static string ServiceIdentifier;
IServiceA myService = new MyService(); // ServiceIdentifier should equal to: "A"
IServiceB myService = new MyService(); // ServiceIdentifier should equal to: "B"
到目前為止,我已經嘗試過:
public class MyService
{
public MyService()
{
if (this is IServiceA)
{
ServiceIdentifier = "A"
}
if (this is IServiceB)
{
ServiceIdentifier = "B"
}
}
}
但這似乎不起作用,因為在兩種情況下它都返回:“ A”,我猜是因為MyService
實現了兩個接口,所以Test()
的第一個if
參數始終為true。
我該如何處理而不必進行依賴注入等?
Edit1 :我要解決的問題是,許多全局參數必須具有不同的值,而我希望這些值取決於實例化MyService
的方式,而不必始終將這些信息注入其構造函數。
不太清楚您要做什么,但是請看一下顯式的接口實現。
示例實現:
interface IServiceA
{
void DoSomething();
}
interface IServiceB
{
void DoSomething();
}
class MyService : IServiceA, IServiceB
{
void DoSomething(string parameter)
{
Console.WriteLine("I'm " + parameter);
}
void IServiceA.DoSomething()
{
DoSomething("service A");
}
void IServiceB.DoSomething()
{
DoSomething("service B");
}
}
測試:
void Main()
{
var service = new MyService();
IServiceA serviceA = service;
serviceA.DoSomething();
IServiceB serviceB = service;
serviceB.DoSomething();
}
輸出:
我在服務A
我在服務B
也許您應該解釋您的實際問題是什么,以便找到更好的解決方案。
正如Samuel所說,您無法實例化接口。 您可以做的是聲明一個接口類型的變量,如:
IServiceA myService;
您可以向其分配實現該接口的任何類型的對象。 然后,當您像這樣分配變量時(請注意代碼中沒有'new'關鍵字):
IServiceA myService = new MyService();
您將myService
設置為MyService
類型(這很好,因為MyService
實現了IServiceA
)。
但是, MyService
的構造函數不知道實例將被分配給的變量的類型,因此您無法(明智地)使用構造函數將屬性分配給這樣的屬性。
實際上,如果IServiceA和IServiceB相同,那么無論如何您都會遇到一些問題。 假設他們都聲明了一個屬性:
bool Test { get; set; }
然后在MyService
或實現這兩個接口的任何其他類中,您需要將此屬性稱為IServiceA.Test
或IServiceB.Test
我確定這不是您想要的。
我敢肯定,有一種更好的方法來完成您要達到的目標,但是如果您能解釋其背后的更多動機,以便我們能夠提供幫助,那將很有幫助。
編輯:
我試圖猜測您想要做什么,但是請看一看。 假設我們定義一個接口:
public interface IMyService
{
string Name { get; }
}
和兩個類:
public class MyServiceA : IMyService
{
public string Name
{
get
{
return "A";
}
}
}
public class MyServiceB : IMyService
{
public string Name
{
get
{
return "B";
}
}
}
然后我們可以編寫這樣的程序:
private static void Main(string[] args)
{
IMyService testService;
testService = new MyServiceA();
Console.WriteLine(testService.Name); // prints 'A'
testService = new MyServiceB();
Console.WriteLine(testService.Name); // prints 'B'
Console.ReadLine();
}
因此,已將局部變量testService
聲明為IMyService類型,但可以將其分配為MyServiceA
或MyServiceB
類型的對象(因為這兩個都實現了接口)。 然后,您可以在不知道該對象的確切類型的情況下調用接口屬性Name
,如本示例中所示,並且將根據testService
的實際類型返回'A'或'B'。
我希望這很清楚嗎?
編輯2 (對問題的編輯之后):
您希望MyService的實例化方式具有不同的“狀態”,但是您不想將此信息傳遞給構造函數嗎? 然后,您如何希望MyService知道它應該做什么?
當然,您不必在構造函數中傳遞所有信息。 您可以這樣定義MyService
類:
public class MyService
{
public MyService(string letter)
{
if (letter == "A")
{
this.Name = "Service A";
// Set other property values for service A
}
else if (letter == "B")
{
this.Name = "Service B";
// Set other property values for service B
}
else
{
throw new NotImplementedException();
}
}
public string Name { get; set; }
}
然后像這樣編寫程序:
private static void Main(string[] args)
{
MyService testService;
testService = new MyService("A");
Console.WriteLine(testService.Name); // prints 'Service A'
testService = new MyService("B");
Console.WriteLine(testService.Name); // prints 'Service B'
Console.ReadLine();
}
因此,通過將一個單字符的字符串傳遞給構造函數(還有更好的方法,這只是一個示例/概念證明),您可以在沒有接口的情況下實現所需的操作。
如果將一個類定義為實現兩個接口,則該類的每個實例化都將實現兩個接口。 您不必通過將類的引用分配給IServiceA或IServiceB類型的變量來更改類的實現。 如果您具有類型IServiceA的變量,則僅將可在基礎對象中訪問的功能/屬性限制為定義為IServiceA的集合。
目前尚不清楚您要在此實現什么,但是也許根本不需要使用接口。 如果您僅使用一個表示服務類型的屬性來構造MyService對象,然后將其保存為構造函數中的私有成員變量,則可以在對象生命周期的以后根據需要通過只讀屬性訪問該成員變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.