Как Вы вызываете подписи конструктора и статические методы?

вы имеете в виду что-то вроде этого?

List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};

это инициализация списка массивов во время создания (hack)

24
задан Alexei Levenkov 28 July 2016 в 18:40
поделиться

9 ответов

Не осуществленный во время компиляции, но я провел много времени, смотря на подобные проблемы; универсально-поддерживающая библиотека математики , и эффективный ctor API (не по умолчанию) оба avaiable в MiscUtil. Однако они только проверяются при первом использовании во времени выполнения. В действительности это не большая проблема - Ваши модульные тесты должны найти любой недостающий оператор / ctor очень быстро. Но это работает, и очень быстро...

8
ответ дан Marc Gravell 29 November 2019 в 00:01
поделиться

Используя дженерики можно вынудить аргумент типа иметь конструктора без параметров - но это о пределе его.

Кроме в дженериках, это было бы хитро к на самом деле использование эти ограничения, даже если бы они существовали, но это могло бы иногда быть полезно для параметров/аргументов типа. Разрешение статических участников в интерфейсах (или возможно статических интерфейсах) могло аналогично помочь с "универсальным числовым оператором" проблеме.

я записал об этом только что при направлении с подобной проблемой.

10
ответ дан Jon Skeet 29 November 2019 в 00:01
поделиться

Вы могли использовать Шаблон "фабрика".

interface Fruit{}

interface FruitFactory<F extends Fruit>{
   F newFruit(String color,double weight);

   Cocktail mixFruits(F f1,F f2);
}

Вы могли тогда создать классы для любого типа Фруктов

class Apple implements Fruit{}
class AppleFactory implements FruitFactory<Apple>{
   public Apple newFruit(String color, double weight){
       // create an instance
   }
   public Cocktail mixFruits(Apple f1,Apple f2){
       // implementation
   }
}

, Это не осуществляет это, Вы не можете создать экземпляр в другом отношении, чем при помощи Фабрики, но по крайней мере можно определить, какие методы Вы вызвали бы от Фабрики.

6
ответ дан jrudolph 29 November 2019 в 00:01
поделиться

Вынудите Конструкторов

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

class Base
{
  private Base() { }
  public Base(int x) {}
}

class Derived : Base
{
  //public Derived() { } won't compile because Base() is private
  public Derived(int x) :base(x) {}
  public Derived() : base (0) {} // still works because you are giving a value to base
}
4
ответ дан jop 29 November 2019 в 00:01
поделиться

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

Статические методы являются просто глобальными методами с пространством имен, они действительно "не принадлежат" классу, в котором они определяются (хорошо, у них есть доступ к частным (статическим) методам в классе, но это об этом).

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

я думаю, что можно было заставить его работать путем добавления глобальной/статичной виртуальной таблицы для каждого класса, но если это еще не было сделано, существует, вероятно, серьезное основание для него.

1
ответ дан TToni 29 November 2019 в 00:01
поделиться

Вот, я решил бы его, если бы я был разработчиком языка.

Позволяют интерфейсам включать статические методы, операторы и конструкторов.

interface IFoo  
{  
  IFoo(int gottaHaveThis);  
  static Bar();  
}

interface ISummable
{
      operator+(ISummable a, ISummable b);
}

не позволяют соответствие new IFoo(someInt), или IFoo.Bar()

Позволяют конструкторам быть наследованными (точно так же, как статические методы).

class Foo: IFoo
{
  Foo(int gottaHaveThis) {};
  static Bar() {};
}

class SonOfFoo: Foo 
{
  // SonOfFoo(int gottaHaveThis): base(gottaHaveThis); is implicitly defined
}

class DaughterOfFoo: Foo
{
  DaughhterOfFoo (int gottaHaveThis) {};
}

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

ISummable PassedFirstGrade = (ISummable) 10; 
1
ответ дан Sklivvz 29 November 2019 в 00:01
поделиться

К сожалению, Вы не можете в C#. Вот перфорация в нем хотя:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Foo.Instance.GetHelloWorld());
        Console.ReadLine();
    }
}

public class Foo : FooStaticContract<FooFactory>
{
    public Foo() // Non-static ctor.
    {
    }

    internal Foo(bool st) // Overloaded, parameter not used.
    {
    }

    public override string GetHelloWorld()
    {
        return "Hello World";
    }
}

public class FooFactory : IStaticContractFactory<Foo>
{
    #region StaticContractFactory<Foo> Members

    public Foo CreateInstance()
    {
        return new Foo(true); // Call static ctor.
    }

    #endregion
}

public interface IStaticContractFactory<T>
{
    T CreateInstance();
}

public abstract class StaticContract<T, Factory>
    where Factory : IStaticContractFactory<T>, new() 
    where T : class
{
    private static Factory _factory = new Factory();

    private static T _instance;
    /// <summary>
    /// Gets an instance of this class. 
    /// </summary>
    public static T Instance
    {
        get
        {
            // Scary.
            if (Interlocked.CompareExchange(ref _instance, null, null) == null)
            {
                T instance = _factory.CreateInstance();
                Interlocked.CompareExchange(ref _instance, instance, null);
            }
            return _instance;
        }
    }
}

public abstract class FooStaticContract<Factory>
    : StaticContract<Foo, Factory>
    where Factory : IStaticContractFactory<Foo>, new() 
{
    public abstract string GetHelloWorld();
}
1
ответ дан Jonathan C Dickinson 29 November 2019 в 00:01
поделиться

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

конструктор А предназначается, чтобы быть характерным для конкретного класса, как он предназначается для инициализации определенных потребностей класса. Насколько я понимаю, причина, с которой Вы хотели бы осуществить что-то в иерархии классов или соединить интерфейсом, то, что это - действие/операция, относящееся к выполняемому процессу, но может варьироваться по различным обстоятельствам. Я полагаю, что это - намеченное преимущество полиморфизма, который Вы не можете достигнуть статических методов использования.

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

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

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

, Если бы это предназначается, чтобы позволить Вам создавать различные экземпляры во времени выполнения, тогда я рекомендовал бы использовать статический метод для абстрактного базового класса, который знает различные потребности всех реальных классов (Вы могли использовать внедрение зависимости для этого).

0
ответ дан marcj 29 November 2019 в 00:01
поделиться

Ну, я знаю от формулировки Вашего вопроса, Вы ищете осуществление времени компиляции. Если у кого-то еще нет блестящего предложения/взлома, которое позволит Вам делать это путь, Вы подразумеваете, что компилятор должен, я предположить, что Вы могли записать пользовательскую задачу MSbuild, которая сделала это. Платформа AOP как PostSharp могла бы помочь Вам выполнить это в comiple-разовом свиной поддержкой на, он - модель задачи сборки.

, Но что не так с анализом кода или осуществлением во время выполнения? Возможно, это - просто предпочтение, и я уважаю это, но у меня лично нет проблем с наличием проверки CA/FXCop эти вещи... и если Вы действительно хотите вынудить нисходящих лиц, осуществляющих внедрение своих классов иметь подписи конструктора, можно всегда добавлять регистрацию времени выполнения правил в конструкторе базового класса, использующем отражение.

Richard

0
ответ дан ZeroBugBounce 29 November 2019 в 00:01
поделиться