Нужна помощь в понимании дженериков C # - PullRequest
2 голосов
/ 30 марта 2009

Я изучаю справочник по C #, и он дает следующую информацию:

части 1.21.4. Объявление общих параметров Общие параметры могут быть введены в объявлении классов, структур, интерфейсов, делегатов (см. Следующий раздел «Делегаты») и методов. Другие конструкции, такие как свойства, не могут вводить универсальный параметр, но могут использовать универсальный параметр. Например, свойство Value использует T:

public struct Nullable<T>
{
  public T Value {get;}
}

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

Во-вторых, предполагая, что это неправильно, и я исправляю это, добавляя «set;», я не могу успешно отформатировать вызов.

Ответы [ 5 ]

8 голосов
/ 30 марта 2009

Это просто показывает API Nullable<T>, а не реализацию. Он не предназначен для компиляции - System.Nullable<T> является частью фреймворка, вам не нужно реализовывать его самостоятельно.

3 голосов
/ 30 марта 2009

Вы, кажется, читаете "C # 3.0 в двух словах". Ну, пример только это - пример. Он предназначен только для иллюстрации того, как свойство Value класса Generic Nullable предоставляет общий параметр, объявленный содержащим типом.

Это не должно быть частью компилируемого примера.

2 голосов
/ 30 марта 2009

Я не уверен, что вы просто выбрали неверный пример для своего имени структуры (поскольку Nullable является структурой структуры), но если нет, ошибка связана с тем, что в вашем свойстве нет установленного метода доступа. Для автоматических свойств (добавленных в C # 3.0) требуется свойство get и set. Итак, если вы измените код на:

public struct Nullable<T>
{
  public T Value {get; set; }
}

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

Nullable<int> i = new Nullable<int>();

Это сделает компиляцию. Однако, как указали и Джон, и Серебр, это, вероятно, просто пример, демонстрирующий работу дженериков.

1 голос
/ 30 марта 2009

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

//tradition 
private T _value; 
public T Value 
{ 
    get 
    {
        return _value;
    }
}
//locally, _value can always be set

//Auto-matically implemented property
public T Value { get; }
//there is never a way to set it

//with this it can be privately set, but is get only to everyone else
public T Value{ get; private set; }
0 голосов
/ 30 марта 2009

Ваш вопрос здесь, похоже, об авто-свойствах, а не об универсальных.

У авто-свойств должен быть установлен аксессор, хотя он не должен иметь ту же видимость, что и get:

public T Value { get; private set; }

Вы можете вызвать набор в конструкторе:

public Nullable ( T value ) {
    Value = value;
}

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

В .net уже есть обнуляемый универсальный:

Nullable<int> i = GetCounterThatMightBeNull();

int j = 0;
if( i.HasValue )
    j = i.Value;
...

Это было добавлено в .Net 2 (одновременно с дженериками), и хотя ранние бета-версии выглядели как код выше, они упростили его до окончательной версии:

//int? is shorthand for Nullable<int>
int? i = GetCounterThatMightBeNull(); 

// ?? is shorthand for the null check
int j = i ?? 0;

//or
if( i == null ) {
    //this works even though Nullable<int> is a struct
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...