简体   繁体   English

如何在c#中将接口转换为类型?

[英]How can I cast an Interface as its type in c#?

I have a property that returns an interface. 我有一个返回接口的属性。 During debugging I can break on what was returned and while it is the interface, Visual Studio is smart enough to know the derived type that it actually is. 在调试期间,我可以打破返回的内容,当它是界面时,Visual Studio足够聪明,可以知道它实际上是派生类型。 I assume it's using reflection or something. 我假设它使用反射或其他东西。 I'm not sure. 我不确定。 My question is, can I have that same info available to me at runtime so I can create a variable of the appropriate type and cast the interface as that? 我的问题是,我可以在运行时向我提供相同的信息,这样我就可以创建一个适当类型的变量并将接口转换为那样的接口吗? Here is what I am saying: 这就是我的意思:

IPreDisplay preDisplay = cb.PreDisplay;

If preDisplay is a RedPreDisplay I would like to be able to code 如果preDisplay是RedPreDisplay,我希望能够编码

RedPreDisplay tmp = preDisplay as RedPreDisplay;

Or if preDisplay were a GreenPreDisplay... 或者如果preDisplay是GreenPreDisplay ......

GreenPreDisplay tmp = preDisplay as GreenPreDisplay;

etc... I would like to avoid a messy switch statement if possible, and If I could use generics that would be great. 等...如果可能的话,我想避免使用凌乱的switch语句,如果我可以使用非常棒的泛型。

If you have any advice or examples of how I can do this, please share. 如果您对我如何做到这一点有任何建议或示例,请分享。

When you hit a situation where you need to do this, it means you're doing something wrong. 当你遇到需要这样做的情况时,这意味着你做错了什么。 You need to back up and figure out why your design demands that you do this. 您需要备份并找出您的设计要求您执行此操作的原因。 If you find yourself stuck there, I strongly recommend you post a new question to get help with the design - there are a lot of smart people here who can help. 如果您发现自己被困在那里,我强烈建议您发布一个新问题以获得设计方面的帮助 - 这里有很多聪明人可以提供帮助。

To answer your question directly, no - you cannot do this without some kind of if/else or conditional, because you have to be explicit with static types. 要直接回答你的问题,不 - 如果没有某种if / else或条件,你不能这样做,因为你必须明确静态类型。 You could use reflection to call the method, but since you seem to need to call something the interface does not support - but some objects do - you would need to code a per-static-type condition anyway to call that method. 您可以使用反射来调用该方法,但由于您似乎需要调用接口不支持的东西 - 但是某些对象会这样做 - 您需要编写一个每静态类型的条件来调用该方法。 Just code the types directly. 只需直接编码类型。

Edit: per the discussion in the comments, the best solution to this is to add a second interface to the classes which have this other property or method. 编辑:根据评论中的讨论,最好的解决方案是向具有此其他属性或方法的类添加第二个接口。 Then you can do a simple check: 然后你可以做一个简单的检查:

IPreDisplay display = cb.PreDisplay;
IOtherInterface displayAsOther = display as IOtherInterface;
if(displayAsOther != null)
{
    displayAsOther.OtherMethod();
}

The entire purpose of using interfaces is that the executing code does not have to be aware of the exact type . 使用接口的整个目的是执行代码不必知道确切的类型 Try to expose all the information you might need via the interface itself, so you have no need to cast. 尝试通过界面本身公开您可能需要的所有信息,因此您无需进行投射。

Understandably, you may still need to cast an interface to a concrete implementation (specific type) on a rare occasion. 可以理解的是,您可能仍需要在极少数情况下将接口强制转换为具体实现(特定类型)。 If you could provide a bit more context, that might be helpful. 如果您可以提供更多上下文,那可能会有所帮助。

Depending on what it is you're trying to do, you should probably add an action method/ property to the interface, that way you don't need to know the type - which is polymorphism. 根据你正在尝试做的事情,你应该向接口添加一个动作方法/属性,这样你就不需要知道类型 - 这是多态。

Eg: 例如:

 IResultLiteEntity preDisplay = cb.PreDisplay;
 preDisplay.Render (); // New Render method on the interface...

@Rex M is absolutely correct. @Rex M绝对正确。 The problem lies with your code and the underlying structure. 问题在于您的代码和底层结构。 As a rule, you should not do what you are trying to do; 作为一项规则,你不应该做你想做的事情; code against the interface only . 针对接口的代码。

That said, there is the is operator that might help you if you've inherited bad code and need to monkey-patch it. 这就是说,有是is运营商,可能会帮助你,如果你已经继承了恶意代码,需要猴子修补它。 For example: 例如:

if(myInstance is MyBaseType)
{
  MyBaseType myInstanceAsBaseType = myInstance as MyBaseType;
  // handle MyBaseType specific issue
}
else if(myInstance is MyOtherBaseType)
{
  MyOtherBaseType myInstanceAsOtherBaseType = myInstance as MyOtherBaseType;
  // handle MyOtherBaseType specific issue.
}

Generics will not help you, nor will you be able to do this as part of a switch statement. 泛型不会帮助您,也不能将此作为switch语句的一部分。 But it'll get you something working, albeit working in a very ugly way. 但它会给你一些工作,虽然工作非常丑陋。

As other responders have pointed out, you probably should consider why your design requires different logic for different types that can't be pulled up into an interface. 正如其他响应者所指出的那样,您可能应该考虑为什么您的设计需要针对不能被拉入接口的不同类型的不同逻辑。

However, assuming that there are good reasons for this, you only have a few options: 但是,假设有充分的理由,您只有几个选择:

  1. Use reflection. 使用反射。 This is generally slow and error prone code, that's also fragile when your implementation changes (ie methods are renamed, etc). 这通常是缓慢且容易出错的代码,当您的实现发生更改(即重命名方法等)时,代码也很脆弱。
  2. Use an if/else if/else pattern to dispatch based on runtime checks of the type. 使用if / else if / else模式根据类型的运行时检查进行分派。 This is pretty much your only other choice in pre-4.0 versions of C#. 这几乎是您在4.0之前版本的C#中唯一的其他选择。
  3. If you are using C# 4.0, you can use assign the object to a dynamic var , and at runtime dispatch to an overloaded method whose signature varies for each of the types supported (see example below). 如果您使用的是C#4.0,则可以使用将对象分配给动态var ,并在运行时分配给重载方法,该方法的签名因所支持的每种类型而异(请参见下面的示例)。

Here's a C# 4.0 dynamic dispatch example: 这是一个C#4.0动态调度示例:

void Foo()
{
  dynamic preDisplay = cb.PreDisplay;
  DoSomethingWith( preDisplay );  // runtime dispatch using dynamic runtime (DLR)
}

void DoSomethingWith( RedPreDisplay r ) { ... }  // code specific to RefPreDisplay
void DoSomethingWith( GreenPreDisplay g ) { ... } // code specific to GreenPreDisplay
void DoSomethingWIth( IPreDisplay o ) { ... }  // catch-all

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 PowerShell 中从 C# 执行这种接口类型的转换? - How can I do this interface type of cast from C# in PowerShell? 在C#中,如果我的对象支持该接口,我如何检查T是否为IInterface类型并强制转换为? - In C# how can i check if T is of type IInterface and cast to that if my object supports that interface? 我可以将未知对象转换为接口,以便可以在C#中访问其属性吗? - Can I cast an unknown object to an interface so I can access its properties in C#? 在 C# 中,如何将接口转换为扩展接口的接口? - In C#, how can I cast an interface to an interface which extends the interface? 如何将对象类型转换为短类型? (C#) - How can I cast an object type to a short type? (C#) 为什么不能将强制转换接口键入其具体实现? - Why can I not type cast Interface into its concrete implementation? 在C#中为什么我可以将接口转换为任何类型而没有编译器错误 - in c# why I can cast an interface to any type without a compiler error C# 如何将泛型类型转换为它实现的接口 - C# How to cast a generic type to interface it implements 如何将命令对象投射到其通用接口? - How can I cast my command object to its generic interface? 如何将接口用作 C# 泛型类型约束? - How can I use interface as a C# generic type constraint?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM