Почему IsNan является статическим методом для двойного класса вместо свойства экземпляра?

Пароль по умолчанию для любого примера приложения RailsApp для «user@example.com» - «changeme». Это задокументировано в файле README для любого примера приложения RailsApp.

12
задан Julien Roncaglia 16 December 2008 в 10:04
поделиться

6 ответов

Интересный вопрос; не знайте ответ - но если бы он действительно прослушивает Вас, Вы могли бы объявить дополнительный метод, но он все еще использовал бы стек и т.д.

static bool IsNaN(this double value)
{
    return double.IsNaN(value);
}

static void Main()
{
    double x = 123.4;
    bool isNan = x.IsNaN();
}

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


Обновление; при размышлении об этом существует другое различие между помехами и экземпляром; C# всегда называет методы экземпляра с"callvirt"вместо"call", даже если там вводят, изолируется не допускающее NULL-значения. Таким образом, возможно, существует выигрыш в производительности от наличия его статичен? К счастью дополнительные методы все еще рассчитывают как статичные, таким образом, Вы добираетесь для сохранения этого поведения.

9
ответ дан 2 December 2019 в 05:42
поделиться

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

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

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

Править: @VirtualBlackFox, который я подготовил и пример, чтобы показать, что методы экземпляра для структур не ориентированы на многопотоковое исполнение даже на неизменных структурах:

using System;
using System.Threading;

namespace CA64213434234
{
    class Program 
    {
        static void Main(string[] args)
        {
            ManualResetEvent ev = new ManualResetEvent(false);
            Foo bar = new Foo(0);
            Action a =  () => bar.Display(ev);
            IAsyncResult ar = a.BeginInvoke(null, null);
            ev.WaitOne();
            bar = new Foo(5);
            ar.AsyncWaitHandle.WaitOne();
        }
    }

    public struct Foo
    {
        private readonly int val;
        public Foo(int value)
        {
            val = value;
        }
        public void Display(ManualResetEvent ev)
        {
            Console.WriteLine(val);
            ev.Set();
            Thread.Sleep(2000);
            Console.WriteLine(val);
        }
    }
}

Печать Метода экземпляра дисплея: 0 5

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

14
ответ дан 2 December 2019 в 05:42
поделиться

@Pop Catalin: я не соглашаюсь с тем, в чем Вы сказали:

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

Вот небольшая программа, которые демонстрируют, что статические методы не решают эту проблему для структур:

using System;
using System.Threading;
using System.Diagnostics;

namespace ThreadTest
{
    class Program
    {
        struct SmallMatrix
        {
            double m_a, m_b, m_c, m_d;

            public SmallMatrix(double x)
            {
                m_a = x;
                m_b = x;
                m_c = x;
                m_d = x;
            }

            public static bool SameValueEverywhere(SmallMatrix m)
            {
                return (m.m_a == m.m_b)
                    && (m.m_a == m.m_c)
                    && (m.m_a == m.m_d);
            }
        }

        static SmallMatrix s_smallMatrix;

        static void Watcher()
        {
            while (true)
                Debug.Assert(SmallMatrix.SameValueEverywhere(s_smallMatrix));
        }

        static void Main(string[] args)
        {
            (new Thread(Watcher)).Start();
            while (true)
            {
                s_smallMatrix = new SmallMatrix(0);
                s_smallMatrix = new SmallMatrix(1);
            }
        }
    }
}

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

Таким образом, потокобезопасность не кажется серьезным основанием для IsNaN для помех:

  1. Платформа должна быть агностиком платформы и таким образом, она не должна предполагать вещи как архитектура процессора. Потокобезопасность IsNaN зависит от того, что к значениям на 64 бита всегда получают доступ и изменяют атомарно на целевой архитектуре (И Компактные цели платформы не являются x86...).
  2. IsNaN бесполезен отдельно и в контексте, где несколько распараллеливают, мог получить доступ someVar этот код так или иначе небезопасен (независимо от потокобезопасности IsNaN):
print("code sample");
if (!double.IsNaN(someVar))
    Console.WriteLine(someVar);

То, что я имею в виду, является этим, даже если IsNaN реализован путем выполнения == сравнения со всеми возможными значениями NaN... (не действительно возможный)..., кто заботится, что значение развивается во время осуществления метода, если так или иначе это, возможно, изменилось однажды метод, оконечный... или это могло бы даже быть промежуточное значение, которое никогда не должно было быть здесь, если целевая архитектура не является x86...

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

4
ответ дан 2 December 2019 в 05:42
поделиться

Различие между экземпляром и a static ключевой момент, который язык C# (и Java, как Вы говорите) принимает решение ясно дать понять (в C++, можно назвать a static метод через экземпляр, но это - просто синтаксис - под экземпляром капота. StaticX является тот же Класс экземпляра высказывания. StaticX.

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

0
ответ дан 2 December 2019 в 05:42
поделиться

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

Я действительно не знаю, почему, и не думали на позади, но логически, это кажется хорошим. Заинтересованный ответом во всяком случае ;-)

0
ответ дан 2 December 2019 в 05:42
поделиться

Я думаю, что Marc был на ответ.

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

0
ответ дан 2 December 2019 в 05:42
поделиться
Другие вопросы по тегам:

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