你可以如何在C#中将一个类转换为具有匹配方法签名的接口?

huangapple go评论73阅读模式
英文:

How can I cast a class to an interface with a matching method signature in C#?

问题

让我们假设我们有一个定义了一个具有签名的接口 IFoopublic void Bar()。我们还有一个定义了多个方法的类 Baz,其中一个方法与 IFoo.Bar 的签名完全相同。Baz 不实现 IFoo,而且不能直接编辑它(只能添加扩展)。如果我们有一个数组 IFoo[],我们想要迭代并调用每个项目的 Bar 方法,我们可以添加任何实现 IFoo 的具体类。我还想将 Baz 对象添加到这个数组中。理想情况下,我们可以简单地将 Bar 转换为 IFoo,但需要定义转换。所以我有两个问题:

  1. 是否可以编写一个转换运算符将 Baz 转换为 IFoo
  2. 是否可以将此转换运算符定义为 Baz 的扩展?

谢谢。

我尝试将 Baz 转换为 IFoo,希望由于它们都包含相同的 Bar 方法签名,并且 IFoo 没有实现 Baz 中未定义的任何属性或方法,它们会被隐式兼容。这导致了 编译器错误 CS0030。我目前的解决方法是拥有两个数组,一个是 IFoo[],另一个是 Baz[]。出于项目特定原因,这不是理想的解决方案。

英文:

Let's say we have an interface IFoo that defines a single method with the signature: public void Bar(). We also have a class Baz that defines multiple methods, one of which has the same exact signature as IFoo.Bar. Baz does not implement IFoo and it cannot be edited directly (we can only add extensions). If we have an array IFoo[] that we want to iterate over and call the Bar method of each item, we could add any concrete class that implements IFoo. I'd like to also add Baz objects to this array as well. Ideally we could simply cast Bar to IFoo but the cast needs to be defined. So I have two questions:

  1. Is it possible to write a conversion operator to cast Baz to IFoo?
  2. Is it possible to defined this conversion operator as an extension of Baz?

Thank you.

I tried casting Baz to IFoo hoping that since they both contain identical Bar method signatures and IFoo does not implement any properties or methods not defined in Baz, they would be implicitly compatible. This led to Compiler Error CS0030. My current work around is to have two arrays one IFoo[] and one Baz[]. For project specific reasons this is not ideal.

答案1

得分: 1

以下是您要翻译的代码部分:

可以构建一个包装类,实现`IFoo`并包装一个`Baz`实例。结合扩展方法,它非常用户友好。

public static class BazExtensions
{
    class FooWrapper : IFoo
    {
        private readonly Baz _baz;
        public FooWrapper(Baz baz)
        {
            _baz = baz;
        }

        void IFoo.Bar() => _baz.Bar();
    }

    public static IFoo AsIFoo(this Baz baz) => new FooWrapper(baz);
}

要从Baz[]获取到IFoo[],您可以使用 Linq:

IFoo[] fooArray = bazArray.Select(b => b.AsIFoo()).ToArray();

dotnetfiddle 上的示例


<details>
<summary>英文:</summary>

You can build a wrapper class that implements `IFoo` and wraps a `Baz` instance. Together with an extension it is very userfriendly.

```cs
public static class BazExtensions
{
	class FooWrapper : IFoo
	{
		private readonly Baz _baz;
		public FooWrapper(Baz baz)
		{
			_baz = baz;
		}
		
		void IFoo.Bar() =&gt; _baz.Bar();
	}
	
	public static IFoo AsIFoo(this Baz baz) =&gt; new FooWrapper(baz);
}

To get from Baz[] to IFoo[] you use Linq

IFoo[] fooArray = bazArray.Select(b =&gt; b.AsIFoo()).ToArray();

example on dotnetfiddle

huangapple
  • 本文由 发表于 2023年5月29日 09:46:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354246.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定