克隆类定义(PCL)



问题:是否可以使用反射克隆类定义?我说的不是浅克隆,也不是深克隆。我说的是定义克隆。我希望有一个类,它的静态变量不是在所有实例之间共享的,而只是我创建的定义。并且我(或库)需要能够在以后从这个类创建一个实例。

问题:您看,我需要这个是因为下面的场景

这个库希望我为它提供一个具有特定静态方法的类型。然而,在我的例子中,这个静态方法需要比较两个值,一个来自另一种类型的非静态字段。这使得不可能将具有信息的实例传递给类,因为它尚未初始化。查看下面的情况示例:

class MasterClass 
{
    public int SomeInfo {get; set;} = 10;
    public void PeresentClass()
    {
        SOMELIBRARY.RegisterType(typeof(StaticClass));
    }
}
class StaticClass
{
    public static bool CanCreate(int someVar)
    {
        // I need to compare someVar with the SomeInfo property of MasterClass instance that presented this type to the SOMELIBRARY.
    }
    public StaticClass()
    {
        // Something irrelevant
    }
}

在上面的例子中,我无法控制SOMELIBRARY和他们决定编写代码的方式。但是,他们似乎想先调用CanCreate方法,然后在满足要求的情况下创建一个类的实例。

然而,为了使CanCreate正确工作,我需要访问首先将StaticClass呈现给SOMELIBRARY的类的实例。我不能把MasterClass设置为静态,因为每次都有多个该类的实例处于活动状态。

我能想到的唯一方法是重新定义一个新的StaticClass,用一个静态字段指向定义它的MasterClass(或克隆定义)。然而,我的反思知识还没有让我做到这一点。所以我想问,这可能吗?我真的希望能够在PCL配置文件下完成。

现实世界

: 为了获得更多的信息,我实际上是在谈论XAMARIN.iOSNSUrlProtocol类,特别是CanInitWithRequest方法。

可能的解决方案:经过更多的思考,我发现解决这个问题的另一种方法是使StaticClass通用;这样做允许我有一个静态变量每个type定义。然而,要做到这一点,我需要能够在运行时创建唯一的、可能为空的类型。这可能吗?

XAMARIN的。iOS:不幸的反射。Emit在iOS上是不可用的,所以现在我不相信这在任何方面都是可能的。我还在等待你对这个情况的评论。

https://developer.xamarin.com/guides/ios/advanced_topics/limitations/System.Reflection.Emit

有许多方法可以在运行时创建类,这似乎是您所要求的。你的问题似乎已经排除了System.Reflection.Emit,所以你可能想探索一些关于这个主题的其他答案,看看它们是否适合你的平台(Xamarin.IOS)。

也就是说,你的问题似乎表明了你的实现中的代码气味。您正在尝试跨API注册函数映射类实例,该函数依赖于静态方法来指示资源是否适合处理请求类型(canInitWithRequest)。这个函数应该只指示注册的NSURLProtocol类是否能够处理特定的请求类型,它可能不应该依赖于系统中另一个对象的某些类属性。

一个更好的方法可能是让你的NSURLProtocol实例在运行时被底层框架调用时查找共享资源。例如,如下所示:

static class SystemMap {
    // Store some mapping information in a commonly accessible system resource
    // In this case a simple static class that wraps up a dictionary
    static Dictionary<Type, Master> systemMap = new Dictionary<Type, Master>();
    // Allow registered components to be accessed
    public static Master getRegisteredMaster(Type handlerType) {
        return systemMap[handlerType];
    }
    // Allow new registrations to be made in your system
    public static void registerNewMaster(Master registrant, Type handlerType) {
        systemMap[handlerType] = registrant;
    }
}
class Master {
    // This would be your custom class that you instantiate throughout your system
    public string name;
    public int someVar { get; set; } = new Random().Next(1, 100);
    public Master(string name) {
        this.name = name;
    }
}
class BaseHandlerType {
    // This would be NSURLProtocol
}
class Handler1 : BaseHandlerType {
    // This would be canInitWithRequest
    public static bool CanCreate(int someVar) {
        Master myMaster = SystemMap.getRegisteredMaster(typeof(Handler1));
        return someVar > myMaster.someVar;
    }
}
class Handler2 : BaseHandlerType {
    //... Register various handler types to various "Master" instances in your system
    // This is a concrete implementation of NSURLProtocol
}
class Handler3 : BaseHandlerType {
    //... Register various handler types to various "Master" instances in your system
    // This is a concrete implementation of NSURLProtocol
}
class SystemFactory {
    // Use a factory method to instantiate the system components and plug things together
    public void initializeSystem() {
        var masterA = new Master("a");
        var masterB = new Master("b");
        var masterC = new Master("c");
        SystemMap.registerNewMaster(masterA, typeof(Handler1));
        SystemMap.registerNewMaster(masterB, typeof(Handler2));
        SystemMap.registerNewMaster(masterC, typeof(Handler3));
        SomeLibrary.register(typeof(Handler1));
        SomeLibrary.register(typeof(Handler2));
        SomeLibrary.register(typeof(Handler3));
    }
}
static class SomeLibrary {
    public static void register(Type handlerType) {
        // This represents the API registration
    }
}

此模式可以帮助您建立组件之间的关系,您试图通过在运行时创建类来实现这些关系。此模式允许各种不同类型的处理程序(即NSURLProtocol类)在调用它们时访问不同的Master实例。在本例中,masterA映射到Handler1, masterB映射到Handler2,以此类推。

经过大量的搜索,我发现没有办法在Xamarin下用c#创建一个空类型。因此,我不得不修改我的代码,以符合苹果API的期望。

在我的例子中,我最终保留了MasterClassStaticClass中使用的所有实例的列表;构造函数和静态方法都遍历列表,并将所需的MasterClass与请求进行匹配。这里有这样做的风险,您最终会有内存泄漏,因为MasterClass的实例永远不会被收集,但在我的情况下,这不是一个问题。

相关内容

  • 没有找到相关文章