简体   繁体   English

我可以使用通用返回类型而不必向下转换吗?

[英]Can I use a generic return type without having to downcast?

I have 2 different types of credential objects in my code. 我的代码中有2种不同类型的凭据对象。

What I'm trying to do is use a generic function to construct and return the correct object based on Object.TYPE 我正在尝试使用通用函数来构造并基于Object.TYPE返回正确的对象

So essentially I want to change the return type and the construction based on whatever condition. 所以本质上我想根据任何条件更改返回类型和构造。

My code seems to be working but in my implementation I need to use a forced downcast . 我的代码似乎可以正常工作,但是在实现中,我需要使用forced downcast

I also had to create a "dummy protocol " for my 2 different credentials which also seems "wrong" 我还必须为我的2个不同的凭证创建一个"dummy protocol ”,这似乎也是“错误的”

This makes me suspicious that Im going about it the wrong way. 这使我怀疑我会以错误的方式进行操作。

How can I do this without downcasting? 我如何才能做到这一点而无需垂头丧气?

public protocol C {    
}

// Generic Creation method //通用创建方法

public enum Credentials {
    case CredentialsIA(apiKey: String, apiSecret: String)
    case CredentialsO(username: String, secret: String, ipsName: String)
    func crendential<T:C>( type: T.Type) -> T {
        switch self {
        case .CredentialsIA(let apiKey, let apiSecret):
            return IACredentials(kAPIKey: apiKey, kAPISecret: apiSecret) as! T
        case .CredentialsO(let username, let secret, let ipsName):
              return OCredential(kUsername: username, kAPIKey: secret, kIPSName: ipsName) as! T
        }
    }
}

Credential Types 凭证类型

public struct IACredentials: C {
    public let kAPIKey: String
    public let kAPISecret: String
    public init(kAPIKey: String, kAPISecret: String) {
        self.kAPIKey = kAPIKey
        self.kAPISecret = kAPISecret
    }
}
public struct OCredential: C {
    public let kUsername: String
    public let kAPIKey: String
    public let kIPSName: String
    public init(kUsername: String, kAPIKey: String, kIPSName: String ) {
        self.kUsername = kUsername
        self.kAPIKey = kAPIKey
        self.kIPSName = kIPSName
    }
}

Instantiation 实例化

let credentialsA: Credentials = Credentials.CredentialsIA(apiKey: kAPIKey, apiSecret: kAPISecret)

let credentialsB : Credentials = Credentials.MIPCredentialsOriient(username: "sds", secret: "sdsd", ipsName: "sssd")

Usage after init 初始化后的用法

 let credential:IACredentials = credentialsA.crendential(type: IACredentials.self)

You can't use your specific class without downcasting. 您不能使用您的特定班级,而无需垂头丧气。 But there is another issue. 但是还有另一个问题。

Your code seems like a template method implementation with smething missing. 您的代码似乎像是缺少一些东西的模板方法实现。 Your dummy interface . 您的虚拟interface

I think, you shuold ask this question yourself: What makes CredentialsIA and OCredential same, What is their common point. 我想,您shuold自己问了这个问题: CredentialsIAOCredential相同,它们的共同点是什么? And use this in your interface. 并在您的界面中使用它。 If you can do it, you can use your interface to perform tasks without need to know what their exact type are. 如果可以做到,则可以使用界面执行任务,而无需知道其确切类型。 Otherwise, you need downcasting. 否则,您需要向下转换。

Exaple: 的exaple:

protocol C{
    func myCommonPointFunc() -> Something
}

class CredentialsIA: C{
    func myCommonPointFunc() -> Something{
        //implementation
    }
}

class OCredential: C{
    func myCommonPointFunc() -> Something{
        //implementation
    } 
}

Usage: 用法:

let credentialsA: Credentials = Credentials.CredentialsIA(apiKey: kAPIKey, apiSecret: kAPISecret)
var result = creadentailsA.credential().myCommonPoinFunc()

Also, this method prevents you to pass your class type to your enum 's credential() method. 此外,此方法还防止您将类类型传递给enumcredential()方法。 You can even use factory classes that implement a factory interface instead of an enum 您甚至可以使用实现factory interface而不是enum factory classes

Maybe this link can be helpful. 也许此链接会有所帮助。

暂无
暂无

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

相关问题 如何使用反射从泛型返回所有​​类子类,而不提供特定的泛型类型 - How can I use reflection to return all classes subclassing from a generic, without giving a specific generic type 我可以使用泛型类型参数作为返回类型吗? - Can I use a generic type argument as a return type? 如何实现工厂以返回实现通用接口的类型,而又不提前知道通用类型? - How can I implement a factory to return a type that implements a generic interface, without knowing the generic type ahead of time? 如何向下转换泛型类型的实例? - How to downcast an instance of a Generic type? 我怎样才能转发到班级'E型或至少在没有警告的情况下安全地进行? - How can I downcast to class' type E or at least make it in a safe way without warnings? 如何使用泛型类而不必声明泛型类型 - how to use a class with generics without having to declare the generic type 如何返回一个通用类型的通用对象? - How can I return a generic object, that also has a generic type? 我可以返回所有属于特定泛型类型的泛型对象吗? - Can I return all generic objects that are of a particular generic type? 如何在具有另一个通用类型作为参数的情况下返回通用类型,而这两个参数都需要实现接口? - How do I return a generic type while having another generic type as parameter, both required to implement an interace? 我可以从返回类型的类型中提取 Generic 的类型吗? - Can I extract the type of Generic from a return type's type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM