Существует ли способ сделать конструктора только видимым к родительскому классу в C#?

Я столкнулся с той же проблемой в дочерних компонентах, где изначально она должна была иметь текущее значение Субъекта, а затем подписаться на Субъект для прослушивания изменений. Я просто поддерживаю текущее значение в Сервисе, поэтому оно доступно для доступа к компонентам, например. :

import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class SessionStorage extends Storage {

  isLoggedIn: boolean;

  private _isLoggedInSource = new Subject<boolean>();
  isLoggedIn = this._isLoggedInSource.asObservable();
  constructor() {
    super('session');
    this.currIsLoggedIn = false;
  }
  setIsLoggedIn(value: boolean) {
    this.setItem('_isLoggedIn', value, () => {
      this._isLoggedInSource.next(value);
    });
    this.isLoggedIn = value;
  }
}

Компонент, который нуждается в текущем значении, может просто получить к нему доступ из службы, то есть:

sessionStorage.isLoggedIn

Не уверен, что это правильная практика :)

5
задан Community 23 May 2017 в 12:18
поделиться

9 ответов

Можно сделать sub дочерние классы классов, что-то вроде этого:

public abstract class AbstractClass
{
    public static AbstractClass MakeAbstractClass(string args)
    {
        if (args == "a")
            return new ConcreteClassA();
        if (args == "b")
            return new ConcreteClassB();
    }

    private class ConcreteClassA : AbstractClass
    {
    }

    private class ConcreteClassB : AbstractClass
    {
    }
}

@Vaibhav Это действительно означает, что классы также скрыты. Но это - насколько я знаю единственный способ полностью скрыть конструктора.

Править: Поскольку другие упомянули, что то же самое может быть выполнено с помощью Отражения, которое могло бы на самом деле быть ближе к тому, что требуется иметь место - например, вышеупомянутые ответы метода на реальные классы, являющиеся в том же файле как Абстрактный класс, который, вероятно, не очень удобен. Сказав, что этим путем является хороший 'Взлом', и хороший, если число и сложность реальных классов являются небольшими.

2
ответ дан 13 December 2019 в 19:40
поделиться

Не можете Вы использовать ключевое слово partial для разделения кода для класса во многие файлы?

0
ответ дан 13 December 2019 в 19:40
поделиться

Необходимо ли на самом деле сделать это? При использовании некоторого псевдо шаблона "фабрика" без истинной потребности дизайна в нем Вы только собираетесь сделать свой код тяжелее, чтобы понять, поддержать и расшириться.

Если Вы не должны делать этого, просто реализуйте истинный шаблон "фабрика". Или, больше ALTy, используйте платформу DI/МОК.

0
ответ дан 13 December 2019 в 19:40
поделиться

Если классы находятся в том же блоке, разве Вы не можете сделать конструкторов внутренними?

3
ответ дан 13 December 2019 в 19:40
поделиться

При использовании этого класса в отдельном сервисном блоке можно использовать внутреннее ключевое слово.

public class AbstractClass
{
    public AbstractClass ClassFactory(string args)
    {
        switch (args)
        {
            case "A":
                return new ConcreteClassA();               
            case "B":
                return new ConcreteClassB();               
            default:
                return null;
        }
    }
}

public class ConcreteClassA : AbstractClass
{
    internal ConcreteClassA(){ }
}

public class ConcreteClassB : AbstractClass
{
    internal ConcreteClassB() {}
}
0
ответ дан 13 December 2019 в 19:40
поделиться

При следовании за принятым ответом, если Вы имели открытый интерфейс и заставили частные классы реализовать интерфейс, Вы могли бы затем возвратить указатель на интерфейс, и любой за пределами Вашего родительского абстрактного класса мог затем использовать их (все еще скрывая дочерние классы).

1
ответ дан 13 December 2019 в 19:40
поделиться

Нет, я не думаю, что мы можем сделать это.

1
ответ дан 13 December 2019 в 19:40
поделиться

Мне простое решение состоит в том, чтобы сделать дочерние классы как samjudson упомянутыми. Я хотел бы избежать этого однако, так как это сделает файл моего абстрактного класса намного больше, чем я хотел бы, чтобы это было. Я не пустил бы разделение классов по поводу нескольких файлов для организации.

Без проблем, просто используйте частичное ключевое слово, и можно разделить внутренние классы на столько файлов, сколько Вы желаете. Вы не должны сохранять его в том же файле.

Предыдущий ответ:

Это возможно, но только с отражением

public abstract class AbstractClass
{
    public static AbstractClass MakeAbstractClass(string args)
    {
        if (args == "a")
            return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassA), true);
        if (args == "b")
            return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassB), true);
    }
}

public class ConcreteClassA : AbstractClass
{
    private ConcreteClassA()
    {
    }
}

public class ConcreteClassB : AbstractClass
{
    private ConcreteClassB()
    {
    }
}

и вот другой шаблон, без ужасного MakeAbstractClass (представьте args в виде строки),

public abstract class AbstractClass<T> where T : AbstractClass<T>
{
    public static T MakeAbstractClass()
    {
        T value = (T)Activator.CreateInstance(typeof(T), true);
        // your processing logic
        return value;
    }
}

public class ConcreteClassA : AbstractClass<ConcreteClassA>
{
    private ConcreteClassA()
    {
    }
}

public class ConcreteClassB : AbstractClass<ConcreteClassB>
{
    private ConcreteClassB()
    {
    }
}
6
ответ дан 13 December 2019 в 19:40
поделиться

То, что необходимо сделать, это для предотвращения конструктора по умолчанию, чтобы быть создает. Внутренним может быть изменение в общественности, если классы не находятся в том же блоке.

public abstract class AbstractClass{

 public static AbstractClass MakeAbstractClass(string args)
 {
    if (args == "a")
        return ConcreteClassA().GetConcreteClassA();
    if (args == "b")
        return ConcreteClassB().GetConcreteClassB();
 }
}

public class ConcreteClassA : AbstractClass
{
  private ConcreteClassA(){}

  internal static ConcreteClassA GetConcreteClassA(){
       return ConcreteClassA();
  }
}

public class ConcreteClassB : AbstractClass
{
  private ConcreteClassB(){}
  internal static ConcreteClassB Get ConcreteClassB(){
       return ConcreteClassB();
  }

}
-2
ответ дан 13 December 2019 в 19:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: