基于非执行接口的通用约束 [英] Generic constraint based on non-implementation of interface

查看:102
本文介绍了基于非执行接口的通用约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个工厂服务的应用程序,允许情况下施工,而解决必要的依赖注入。比如,我用这个来构建对话视图模型。我有一个服务界面,看起来是这样的:

I have an application with a factory service to allow construction of instances while resolving the necessary dependency injection. For instance, I use this to construct dialog view models. I have a service interface that looks like this:

public interface IAsyncFactory
{
    Task<T> Build<T>() where T: class, IAsyncInitialize;
}

在理想情况下,我想有是这样的(伪语法,因为这不是直接实现)

Ideally, what I'd like to have is something like this (pseudo-syntax, as this isn't directly achievable)

public interface IFactory
{
    Task<T> Build<T>() where T: class, IAsyncInitialize;

    T Build<T>() where T: class, !IAsyncInitialize;
}

这里的想法是,如果一个类支持 IAsyncInitialize ,我想编译器解析为返回任务项&lt; T&GT; ,这样很明显从消费code,它需要等待初始化。如果该类不支持 IAsyncInitialize ,我想直接返回的类。 C#的语法不允许这样,但有一个不同的方式来实现我后?这里的主要目的是帮助提醒类的正确方法的消费者实例化,所以,对于具有异步初始化组件类,我不尝试使用它,它被初始化之前。

The idea here is that if a class supports IAsyncInitialize, I'd like the compiler to resolve to the method that returns Task<T> so that it's obvious from the consuming code that it needs to wait for initialization. If the class does not support IAsyncInitialize, I'd like to return the class directly. The C# syntax doesn't allow this, but is there a different way to achieve what I'm after? The main goal here is to help remind the consumer of the class of the correct way to instantiate it, so that for classes with an asynchronous initialization component, I don't try to use it before it has been initialized.

我能想到的最接近的是创建单独的构建 BuildAsync 方法,与如果你运行时错误呼吁建立一个 IAsyncInitialize 类型,但是这并没有在编译时捕捉错误的好处。

The closest I can think of is to create separate Build and BuildAsync methods, with a runtime error if you call Build for an IAsyncInitialize type, but this doesn't have the benefit of catching errors at compile time.

推荐答案

在一般微软建议命名异步方法时添加异步后缀。因此,您创建命名为生成两种方法的假设 BuildAsync 是有道理的。

In general Microsoft suggests to add async suffix when naming asynchronous methods. Thus, your assumption of creating two methods named as Build and BuildAsync makes sense.

我觉得没有办法执行类似各类未实现 IAsyncInitialize 将使用构建方法代替 BuildAsync ,除非你强迫开发商以纪念像 ISynchronousInitialize 另一个接口同步的方法。

I think there is no way to enforce something like "all types that do not implement IAsyncInitialize shall use Build method instead of BuildAsync" unless you force the developers to mark synchronous methods with another interface like ISynchronousInitialize.

您可以尝试以下;


  1. 而无需单独的方法,只需要实现它具有以下签名有一个 BuildAsync 方法:

Task<T> BuildAsync<T>() where T: class


  • BuildAsync 方法检查是否 T 工具 IAsyncInitialize 。如果是这样的话,只需要调用相关的初始化code创建类型的对象之后, T 。否则,只需创建一个 TaskCompletionSource 对象和运行同步初始化code,就好像它是异步的。

  • In the BuildAsync method check whether T implements IAsyncInitialize. If this is the case, just call related initialization code after creating the object of type T. Otherwise, just create a TaskCompletionSource object and run the synchronous initialization code as if it is asynchronous.

    这篇关于基于非执行接口的通用约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆