为了账号安全,请及时绑定邮箱和手机立即绑定

无接口的密封类的复合模式

无接口的密封类的复合模式

C#
慕斯709654 2023-08-20 14:50:56
假设我正在使用一个我无法控制的库。该库公开了需要特定类参数的服务。类被标记为密封且没有接口。tl;dr:如何将密封类重新实现为接口?代码示例:using System;namespace IDontHaveControlOverThis{    // Note no interface and the class is being sealed    public sealed class ArgumentClass    {        public String AnyCall() => "ArgumentClass::AnyCall";    }    public sealed class ServiceClass    {        public String ServiceCall(ArgumentClass argument) => $"ServiceClass::ServiceCall({argument.AnyCall()})";    }}namespace MyCode{    // Composite pattern, basically I need: "is a ArgumentClass"    // Obviously doesn't work - can't extend from sealed class    public class MyArgumentClass : IDontHaveControlOverThis.ArgumentClass    {        private IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();        public String AnyCall() => $"MyArgumentCLass::AnyCall({arg.AnyCall()})";    }}public class Program{    public static void Main()    {        // I don't have control over this        IDontHaveControlOverThis.ServiceClass service = new IDontHaveControlOverThis.ServiceClass();        //This obviously works        IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();        Console.WriteLine($"Result: {service.ServiceCall(arg)}");        // How to make this work?        IDontHaveControlOverThis.ArgumentClass myArg = new MyCode.MyArgumentClass();        Console.WriteLine($"Result: {service.ServiceCall(myArg)}");    }}
查看完整描述

2 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

根据您显示的代码示例,答案是您不能。您需要能够IDontHaveControlOverThis.ArgumentClass通过设置属性或创建具有不同构造函数参数的新实例来修改 的行为,以便修改服务调用。(现在它总是返回相同的字符串,因此服务调用始终相同)


如果您能够通过设置属性来修改 ArgumentClass 的行为。您可以在自己的代码中为密封类创建包装器,并在整个代码库中使用它。


public class MyArgumentClass

{

        // TODO: Set this to a useful value of ArgumentClass.

    internal IDontHaveControlOverThis.ArgumentClass InnerArgumentClass { get; }

    public virtual string AnyCall() => "???";

}


public class MyServiceClass

{

    private IDontHaveControlOverThis.ServiceClass innerServiceClass

            = new IDontHaveControlOverThis.ServiceClass();


    public virtual string ServiceCall(MyArgumentClass argument)

    {

        return innerServiceClass.ServiceCall(argument.InnerArgumentClass);

    }

}

或者


public class MyArgumentClass

{

    public virtual string AnyCall() => "???";

}


public class MyServiceClass

{

    private IDontHaveControlOverThis.ServiceClass innerServiceClass

            = new IDontHaveControlOverThis.ServiceClass();


    public string ServiceCall(MyArgumentClass argument)

    {

        var serviceArgument = Convert(argument);

        return innerServiceClass.ServiceCall(serviceArgument);

    }


    private IDontHaveControlOverThis.ArgumentClass Convert(MyArgumentClass argument)

    {

        // TODO: implement.

    }

}



查看完整回答
反对 回复 2023-08-20
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

编译器错误信息


无法将类型“MyCode.MyArgumentClass”隐式转换为“IDontHaveControlOverThis.ArgumentClass”


注意:强调我的


应该给你一个关于你可以做什么的提示


public class MyArgumentClass {

    private IDontHaveControlOverThis.ArgumentClass arg = new IDontHaveControlOverThis.ArgumentClass();


    public String AnyCall() => $"MyArgumentCLass::AnyCall({arg.AnyCall()})";



    public static implicit operator IDontHaveControlOverThis.ArgumentClass(MyArgumentClass source) {


        return source.arg;

    }

}

所以现在你的“包装器”根据需要公开了第 3 方依赖项


 IDontHaveControlOverThis.ArgumentClass myArg = new MyCode.MyArgumentClass();

或直接


var myArg = new MyCode.MyArgumentClass();

Console.WriteLine($"Result: {service.ServiceCall(myArg)}");

这可以允许抽象你的代码


namespace MyCode {


    public interface IMyService {

        String ServiceCall(MyArgumentClass argument);

    }


    public class MyServiceClass : IMyService {

        public string ServiceCall(MyArgumentClass argument) {

            IDontHaveControlOverThis.ServiceClass service = new IDontHaveControlOverThis.ServiceClass();

            return service.ServiceCall(argument);

        }

    }

}


查看完整回答
反对 回复 2023-08-20
  • 2 回答
  • 0 关注
  • 79 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信