2012-02-15 4 views
1

Возможно ли создать класс, который не является структурой, а является типом значения, или он похож на тип значения, поскольку он копируется при передаче вместо передачи по ссылке.Определение класса типа значения в C#?

редактировать:

К сожалению о вопросе того, чтобы быть отредактирован после того, как просили.

Также см. Этот вопрос для получения дополнительной информации. Cycle in the struct layout that doesn't exist

+0

Вы имеете в виду 'Int32',' Int64' и т. Д.? – mmdemirbas

+0

Трудно сказать, что именно вы имеете в виду. В C# классы не являются типами значений. Почему вы спрашиваете об этом? – svick

+0

Вы имеете в виду класс, подобный 'System.String', со значениями, подобными семантике? Потому что, строго говоря, вы объявляете ссылочные типы с помощью 'class' и типов значений с' struct', по определению. Невозможно создать тип значения, используя объявление 'class'. – phoog

ответ

5

EDIT 2

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


Поскольку вы смотрите на создание класса с семантикой, похожими на System.String, вы должны, вероятно, декомпилировать System.String. Большая часть его магии скрыта в CLR, но многое из того, что вы увидите, поможет.

Для начала, вам обязательно нужно перегружать == и !=, и переопределить Equals() и GetHashCode(). Вы почти наверняка захотите реализовать IComparable<T> и IEquatable<T>.

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

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

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

EDIT

В ответ на ваши изменения, вы, кажется, имеют неправильное представление о струнах. Хотя они ведут себя как типы значений в некотором роде, они не передаются напрямую, копируя их данные каждый раз, когда они передаются методу. Единственный способ добиться этого - объявить struct. Строки, как и все классы, являются ссылочными типами, к которым можно обращаться только по ссылке; вы можете напрямую манипулировать ссылкой; вы можете передать только ссылку.

+0

Нет, я думаю, он хотел создать класс типа значения, как примитивный тип! – vulkanino

+0

@vulkanino no, я создал этот ответ в ответ на его комментарий выше. – phoog

+0

ahhh ok, он полностью изменил вопрос! – vulkanino

1
public struct Example 
{ 
    public int Property {get;set;} 
} 

Или, что вы имеете в виду, когда вы просили пример?

+0

Как вы думаете, какая разница? –

+0

@ alan2here 'structs' не являются типами значений" по умолчанию ", они являются типами значений * по определению *. Аналогично, классы являются ссылочными типами * по определению *. – phoog

1

Хотя ValueType является неявным базовым классом для типов значений, вы не можете создать класс, который наследует от ValueType напрямую. Вместо этого отдельные компиляторы предоставляют языковое ключевое слово или конструкцию (например, struct в C# и Structure ... End Structure в Visual Basic) для поддержки создания типов значений.

источник: http://msdn.microsoft.com/en-us/library/system.valuetype.aspx

3

Можно создать класс, имитирующий неизменный семантика значения почти. System.String относится к этой категории. Учитывая экземпляр класса, единственный способ иметь экземпляр, который похож на первый, но каким-то образом отличается, состоит в том, чтобы построить новый экземпляр, основанный на оригинале. Чтобы достичь «неизменяемой семантики значений, почти», класс должен переопределить Object.Equals() и Object.GetHashCode() таким образом, чтобы два экземпляра, которые хранят идентичные данные, сравнивались друг с другом и выдавали один и тот же хэш-код.

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

+0

Хороший ответ, но, как указано в ответе phoog, вы также должны переопределить операторы == и! = Для имитации семантики значения. –

+0

Правда. Было бы также полезно, если бы был способ указать, что конкретные методы экземпляра не следует называть «фактически», что позволяет использовать 'myString.IsNullOrEmpty()', а не 'String.IsNullOrEmpty (myString)'. Если ссылочные типы должны были иметь такую ​​семантику, можно было бы потерять ограничение 'struct' на' Nullable ', что, честно говоря, мне никогда не нравилось. – supercat

Смежные вопросы