C#: Создание экземпляра абстрактного класса, не определяя новый класс

Копируем здесь лучший ответ на вопрос Python Time Seconds to h: m: s , потому что для моих глаз следующее использование divmod и назначение набора так приятно.

hours = 72.345
seconds = hours * 3600
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
print "%d:%02d:%02d" % (h, m, s)

24
задан vipirtti 9 February 2009 в 09:56
поделиться

9 ответов

С lamba выражениями и инициализаторами класса можно получить то же поведение с небольшим количеством усилия.

public class Example {
    public Action DoStuff;
    public Action<int> DoStuffWithParameter;
    public Func<int> DoStuffWithReturnValue;
}

class Program {
    static void Main(string[] args) {
        var x = new Example() {
            DoStuff = () => {
                Console.WriteLine("Did Stuff");
            },
            DoStuffWithParameter = (p) => {
                Console.WriteLine("Did Stuff with parameter " + p);
            },
            DoStuffWithReturnValue = () => { return 99; }


        };

        x.DoStuff();
        x.DoStuffWithParameter(10);
        int value = x.DoStuffWithReturnValue();
        Console.WriteLine("Return value " + value);
        Console.ReadLine();
    }
}

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

Однако нет никакой причины, что Вы не могли передать экземпляр Примера к лямбда-выражениям, которые предоставят им доступ к любому общедоступному состоянию, которое мог бы содержать пример. AFAIK, который был бы функционально эквивалентен Java Анонимный Внутренний Класс.

P.S., Если Вы собираетесь провалить ответ, сделайте нас всех польза и добавьте комментарий относительно того, почему Вы не соглашаетесь :-)

17
ответ дан Darrel Miller 16 October 2019 в 08:18
поделиться

Метод Java называют" Анонимный внутренний класс ", и в C# нет никакого эквивалента.

21
ответ дан Anton Gogolev 16 October 2019 в 08:18
поделиться

Как правило, проблемы, которые решены с анонимными внутренними классами в Java, решены намного более чистым способом с помощью делегатов в .NET. Ваш пример немного слишком упрощен для определения намерения. Если Ваше намерение при помощи абстрактного класса состоит в том, чтобы раздать "поведение", думают о просто использовании Action делегат вместо этого.

public class StartHere{
   public static void main(string[] args){
      Action doStuff = () => Console.WriteLine("Did stuff");
      executeSomething(doStuff);
   }

   public static void executeSomething(Action action)
   {
      action();
   }
}
10
ответ дан Michael Meadows 16 October 2019 в 08:18
поделиться

Это не может быть сделано в C#; необходимо объявить новый тип класса. Самым близким можно войти в C#, является, вероятно, именованный вложенный класс:

public class StartHere{
    private class Foo : Example {
        public override void  doStuff()
        {
            Console.WriteLine("did stuff");
        }
    }
   public static void Main(string[] args){
      Example x = new Foo();
      x.doStuff();
   }
}
8
ответ дан Marc Gravell 16 October 2019 в 08:18
поделиться

Это не поддерживается в C#, и если бы он был мое дело, то это не должно быть так также.

быстрое увеличение внутренних классов в Java происходит главным образом из-за отсутствия делегатов или лямбд, которые имеет C#. Таким образом, в то время как этот тип функциональности в настоящее время является "Вашей единственной надеждой" в Java, можно обычно использовать другие механизмы в C# для достигания тех же целей. Java испытывает желание играть на фортепьяно с одной рукой в этом отношении.

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

1
ответ дан krosenvold 16 October 2019 в 08:18
поделиться

Так как Ваш класс представляет только действие, можно использовать делегата в случае, существует существующий делегат:

public delegate void Action();

Это - точный эквивалент Вашего класса.

И dГ©claration Вашего анонимного класса даже инструмент для очистки:

Action action = () => Console.WriteLine("Hello world");
action(); // invoke

можно даже использовать закрытие:

public void Hello(string name)
{
  Action action = () => Console.WriteLine("Hello " + name);
  action(); // will call the above lambda !
}
1
ответ дан thinkbeforecoding 16 October 2019 в 08:18
поделиться

В то время как вся польза отвечает, большая часть работы arounds предложенный полагаются на C# 3.0

Так, ради полноты, я добавлю другое решение, которое не использует ни лямбд, ни типа Func (Предоставленный, что, как Matt Olenik упомянул в комментариях, можно было обобщить ниже делегатов в работе тот же путь.). Для тех, как я, кто может все еще работать с C# 2.0. Возможно, не лучшее решение, но это работает.

public class Example
{
    public delegate void DoStuffDelecate();
    public DoStuffDelecate DoStuff;
    public delegate void DoStuffWithDelecate(int n);
    public DoStuffWithDelecate DoStuffWithParameter;
    public delegate int DoStuffWithReturnDelecate();
    public DoStuffWithReturnDelecate DoStuffWithReturnValue;
}

class Program
{
    static int MethodWithReturnValue()
    {
        return 99;
    }
    static void MethodForDelecate()
    {
        Console.WriteLine("Did Stuff");
    }
    static void MethodForDelecate(int n)
    {
        Console.WriteLine("Did Stuff with parameter " + n);
    }


    static void Main(string[] args)
    {
        var x = new Example();
        x.DoStuff = MethodForDelecate;
        x.DoStuffWithParameter = MethodForDelecate;
        x.DoStuffWithReturnValue = MethodWithReturnValue;

        x.DoStuff();
        x.DoStuffWithParameter(10);
        int value = x.DoStuffWithReturnValue();
        Console.WriteLine("Return value " + value);
        Console.ReadLine();
    }
}
1
ответ дан vipirtti 16 October 2019 в 08:18
поделиться

Вы можете выполнить это с Насмешкой в.NET. Однако нет никакой поддержки в языке этой функции, я думаю, что это будет доступно в C# 4.0. Существует много библиотек там для Насмешки, включая:

0
ответ дан Nick Berardi 16 October 2019 в 08:18
поделиться

Короче говоря не необходимо определить его как отдельный sub класс. Я думаю, что эта функция прибывает C# 4.0 хотя?

Редактирование: No это не прибывает C# 4.0, я составил это.

0
ответ дан Chris S 16 October 2019 в 08:18
поделиться
Другие вопросы по тегам:

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