2009-02-11 2 views
18

Можно ли скрыть конструктор без параметров от пользователя в C#скрыть конструктор без параметров на структуры

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

например этот класс установки

public struct Position 
{ 
    private readonly int _xposn; 
    private readonly int _yposn; 

    public int Xposn 
    { 
     get { return _xposn; } 
    } 

    public int Yposn 
    { 
     get { return _yposn; } 
    } 

    public Position(int xposn, int yposn) 
    { 
     _xposn = xposn; 
     _yposn = yposn; 
    }   
} 

Я только хочу, чтобы пользователи могли в новом позицию, указав координаты х и у

Однако конструктор без параметров ВСЕГДА Доступно

Я не могу сделать это частный , Или даже определить его как общественное

Я прочитал это Why can't I define a default constructor for a struct in .NET?

но это реально не поможет

Если это не представляется возможным - то, что это лучший способ, чтобы обнаружить, если позиция я передается имеет значения?

Пояснение, проверяющее каждое поле свойств? Есть ли более легкий способ?

благодаря

ответ

19

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

Вы cancreate a private parameterless constructor for a struct, но не в C#. Тем не менее, даже если вы делаете, что это не помогает - потому что вы можете легко работать вокруг него:

MyStruct[] tmp = new MyStruct[1]; 
MyStruct gotcha = tmp[0]; 

Это будет по умолчанию значения MyStruct - «все нули» значение - никогда не вызов конструктора ,

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

+3

Я рассматриваю это как проблему юзабилити больше, чем что-либо еще. Конструктор по умолчанию может создавать объект _valid_, но для многих структур это не то, что пользователь хочет или ожидает. Тем не менее некоторые люди будут использовать этот конструктор по умолчанию только потому, что это первый вариант, который дает их IDE.И тогда у них будут путаные ошибки, вызванные обнуленными структурами, которые должны были быть заполнены данными, или они будут тратить время на попытки выяснить, почему они не могут устанавливать свойства в неизменяемой структуре. С точки зрения API-дизайна мне хотелось бы скрыть конструктор по умолчанию. –

+1

+1 @MB. Частный конструктор по умолчанию поможет, даже если определенный «дурак» может обойти его. Как соль C++, я считаю «частным» как подсказку, чтобы не стрелять в ногу, всегда есть работа с помощью указателей. И семантику массива можно позаботиться, просто не позволяя создавать массивы таких структур. –

+0

@roryapL Исправлено, спасибо. –

2

Ну структура буквально заявление о том, как память будет сидеть.

Даже при использовании объекта указатель объектов IS объявлен независимо от того, является ли он нулевым.

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

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

struct point 
{ 
    int xpos; 
    int ypos; 
} 

Имейте google для неизменяемых объектов, это похоже на то, что вы после. Я считаю, что они хотят добавить эту функцию (но не в C# 4) к самому языку, потому что это общее требование. Существует ли конкретная потребность в структуре здесь?

+0

Что вы подразумеваете под этим? использовать статический анализ, чтобы убедиться, что он проиндексирован Вы имеете в виду проверить, что каждое поле имеет значение? – ChrisCa

+0

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

4

Nope не может скрыть это. Структуры не могут переопределить нулевой конструктор arg, поэтому его видимость не может быть переопределена.

+0

Ну, .NET позволяет вам создавать настраиваемый конструктор без параметров, но вы не можете сделать это * непосредственно * на C#, и это никоим образом не помогает, так как вы можете легко обойти его. –

1

Вы не можете создать структуру с помощью частного конструктора без параметров или даже объявить конструктор без параметров. Вам придется изменить его на класс. Структуры не позволяют объявить конструктор без параметров.

Из Structs Tutorial на MSDN:

Структура может объявить конструкторы, но они должны принимать параметры. Ошибочно объявлять конструктор по умолчанию (без параметров) для структуры. Элементы структуры не могут иметь инициализаторы. Конструктор по умолчанию всегда предоставляется для инициализации членов структуры до значений по умолчанию.

Из C# specification на MSDN:

11.3 класса и Struct различия

структур отличаются от классов в нескольких важных аспектах:

  • Структуры являются типами значений (Раздел 11.3.1 ).
  • Все типы структур неявно наследуют из класса System.ValueType (раздел 11.3.2). Присвоение переменной типа структуры создает копию присваиваемого значения (раздел 11.3.3).
  • Значение по умолчанию для структуры является значения производится путем установки все значения полого типа на их значение по умолчанию и всех полей ссылочного типа обнулить (раздел 11.3.4). Бокс и операции unboxing используются для преобразования между типом структуры и объектом (раздел 11.3.5).
  • Смысл этого отличается от структур (раздел 11.3.6).
  • В объявлениях полей экземпляра для структуры не разрешено включать переменных инициализаторов (раздел 11.3.7).
  • Структуре не разрешено объявлять конструктор экземпляра без параметров (раздел 11.3.8).
  • Структуре не разрешено объявлять деструктором (раздел 11.3.9).
Смежные вопросы