【问题标题】:Nested Abstract Class with Override具有覆盖的嵌套抽象类
【发布时间】:2014-08-16 15:06:13
【问题描述】:

我有一个抽象类用于存储有关 OAuth 令牌的信息:

public abstract class Provider
{
    private readonly string _accessToken;
    private readonly string _refreshToken;
    private readonly JsonMeta _providerMeta;

    protected Provider(TokenProfile profile)
    {
        _accessToken = profile.AccessToken;
        _refreshToken = profile.RefreshToken;
        _providerMeta = 
                  JsonConvert.DeserializeObject<JsonMeta>(profile.JsonMeta);
    }
    protected class JsonMeta {}
}

我使用这个基类来创建具有更具体属性的子类:

public class SalesforceProvider : Provider
{
    public SalesforceProvider(TokenProfile profile) : base(profile)
    {
    }
    //Get unique information from the Json
    protected new class JsonMeta
    {
        public string instance_url;
        public string token_type;
        public string id_token;
    }
    //Salesforce calls must be made to a specific server associated
    //with the users account. Most OAuth calls contain unique
    //metadata like this in their responses that is needed to
    //use their service
    public string SomeData()
    {
        return Salesforce.Leads(_providerMeta.instance_url);
    }
}

但是,上面的方法不起作用,因为JsonMeta是在抽象类中实现的,而类中实现的属性在我们到达派生类之前是不存在的,所以派生类中的JsonMeta对象类没有属性。

但我的问题是,每个派生类的类名和实例化都是相同的,只是属性会根据 JSON 返回中的元数据而改变。

所以我的问题是,我的抽象中是否可以有一个空类,在抽象构造函数中实例化以减少重复,但对派生类中存在的属性这样做?

如果没有,最好的方法是什么?

【问题讨论】:

  • JsonMeta初始化后如何使用,何时使用?
  • 使抽象类泛型?
  • @WiktorZychla 在 salesforces 的情况下,我有数据访问方法需要像 instance_url 这样的信息来进行 REST API 调用,所以我将在 SalesforceProvider 中有一个公共方法,它获取对 @ 的私有引用方法中的987654326@。
  • 顺便说一下,类名不一样。它们可能看起来相同,但它们不能具有相同的完全限定名称,这是编译器使用的。
  • @WiktorZychla 示例添加到问题

标签: c# inheritance design-patterns abstract-class abstraction


【解决方案1】:

使 JsonMeta 抽象化。

public abstract class Provider
{
    private readonly JsonMeta _providerMeta;

    protected Provider(TokenProfile profile, JsonMeta json)
    {
        // do stuff with JsonMeta object
    }

    protected abstract class JsonMeta { }
}

public class SalesforceProvider : Provider
{
    public SalesforceProvider(TokenProfile profile)
        : base(profile, new SalesforceJson())
    { }

    private class SalesforceJson : JsonMeta
    {
        // Salesforce-specific stuff
    }
}

这允许您为不同类型创建不同的 JSON 实现,但仍将它们的使用抽象到 Provider 基类。

【讨论】:

    【解决方案2】:

    这样的事情怎么样(我不知道 profile.JsonMeta 的类型是什么。)

    public abstract class Provider
    {
        private readonly string _accessToken;
        private readonly string _refreshToken;
        private readonly object _jsonMeta;
    
        protected Provider(TokenProfile profile)
        {
            _accessToken = profile.AccessToken;
            _refreshToken = profile.RefreshToken;
            _jsonMeta = profile.JsonMeta;
        }
        protected JsonMeta ProviderMeta
        {
            get
            {
                return JsonConvert.DeserializeObject<JsonMeta>(_jsonMeta); ;
            }
        }
        protected class JsonMeta { }
    }
    

    【讨论】:

    • profile.JsonMeta 是一个字符串,它是 OAuth 令牌响应的原始 JSON 输出。
    • 您可以只将配置文件数据存储在基类中,并在子类中调用 Json。如果不想每次都反序列化,在基类中创建一个protected JsonMeta,并设置为null。第一次从子类调用 ProviderMeta 时,可以填充 JsonMeta 属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多