Если ChildClass означает, что он получен из ParentClass, вы можете просто написать следующее, чтобы принять как ParentClass, так и ChildClass;
public void test<T>(string a, T arg) where T: ParentClass
{
//do something
}
С другой стороны, если вы хотите использовать два разных типа без наследования отношения между ними, вы должны рассмотреть типы, реализующие один и тот же интерфейс:
public interface ICommonInterface
{
string SomeCommonProperty { get; set; }
}
public class AA : ICommonInterface
{
public string SomeCommonProperty
{
get;set;
}
}
public class BB : ICommonInterface
{
public string SomeCommonProperty
{
get;
set;
}
}
, тогда вы можете написать свою общую функцию как:
public void Test<T>(string a, T arg) where T : ICommonInterface
{
//do something
}
Ваша идея осмотреть блок не достаточно хороша; переупорядочение может произойти на аппаратном уровне.
Для ответа на вопрос "это когда-либо проблема на аппаратных средствах чтения": Да! На самом деле я столкнулся с той проблемой сам.
он в порядке для края проблемы с однопроцессорными системами или другими ситуациями особого случая? Я обсудил бы "нет", потому что пять лет с этого времени, на которых Вы, возможно, должны были бы работать многоядерный, в конце концов, и затем находящий все эти местоположения, будут хитры (невозможный?).
Одно исключение: программное обеспечение разработало для встроенных аппаратных приложений, где действительно Вы имеете полностью контроль аппаратными средствами. На самом деле я "обманул" как это в тех ситуациях на, например, процессоре ARM.
Да - используют барьеры памяти для предотвращения инструкции, переупорядочивающей при необходимости. В некоторых компиляторах C++ энергозависимое ключевое слово было расширено для вставки неявных барьеров памяти для каждого чтения и записи - но это не портативное решение. (Аналогично со Взаимно блокируемым* win32 API). Vista даже добавляет некоторые новые Взаимно блокируемые API с более прекрасными зернами, которые позволяют Вам определить семантика записи или чтение.
, К сожалению, C++ имеет такую свободную модель памяти, что любой вид кода как это будет непортативным в некоторой степени, и необходимо будет записать различные версии для различных платформ.
Как Вы сказал, из-за переупорядочения сделанного в кэше или уровне процессора, Вам на самом деле нужен своего рода барьер памяти для обеспечения надлежащей синхронизации, специально для многопроцессорных систем (и особенно на non-x86 платформах). (Мне дают, чтобы полагать, что однопроцессорные системы не имеют этих проблем, но не заключают мне в кавычки на этом---, я, конечно, более склонен действовать наверняка и сделать синхронизируемый доступ так или иначе.)
Мы столкнулись с проблемой, хотя на процессорах Itanium, где переупорядочение инструкции более агрессивно, чем x86/x64.
фиксация должна была использовать Взаимно блокируемую инструкцию, так как не было (в то время) никакой способ сказать компилятор просто, но барьер записи после присвоения.
Нам действительно нужно расширение языка для контакта с этим чисто. Использование энергозависимых (если поддерживается компилятором) является слишком крупномодульным для случаев, где Вы пытаетесь сжать как можно больше производительности из части кода.
это - когда-нибудь проблема на реальных аппаратных средствах?
Абсолютно, особенно теперь с перемещением к нескольким ядрам для текущих и будущих центральных процессоров. Если Вы зависите от заказанной атомарности для реализования опций в приложении, и Вы неспособны гарантировать это требование через свою выбранную платформу или использование примитивов синхронизации, под весь условия т.е. потребительские перемещения от одножильного ЦП до многоядерного ЦП, то Вы просто ожидаете проблемы произойти.
Заключение в кавычки от упомянутого статья Herb Sutter (вторая)
Заказанные атомарные переменные записаны по-разному на популярных платформах и средах. Например:
volatile
в C#/.NET, как вvolatile int
.volatile
или * Атомарный* в Java, как вvolatile int
,AtomicInteger
.atomic<T>
в C++ 0x, предстоящий Стандарт C++ ISO, как вatomic<int>
.
я не видел, как C++ 0x реализует заказанную атомарность, таким образом, я неспособен определить, является ли предстоящая функция языка чистой реализацией библиотеки или полагается на изменения в языке также. Вы могли рассмотреть предложение видеть, может ли оно быть включено как нестандартное расширение Вашего текущего набора инструментальных средств, пока новый стандарт не доступен, это уже может даже быть доступно для Вашей ситуации.
Это - проблема на реальных аппаратных средствах. Мой друг работает на IBM и зарабатывает на жизнь, прежде всего, путем разузнавания этого вида проблемы в кодах клиентов.
, Если Вы хотите видеть, как плохие вещи могут добраться, поиск научных работ на Модели памяти Java (и также теперь модели памяти C++). Учитывая переупорядочение, которое реальные аппаратные средства могут сделать, пытаясь выяснить то, что безопасно на высокоуровневом языке, кошмар.
Ответ на вопрос", это безопасный" по сути неоднозначно.
Это всегда безопасно, даже для удваивается, в том смысле, что Ваш компьютер не загорится. Это безопасно, в том смысле, что Вы всегда будете получать значение, которое интервал содержал в некоторое время в прошлом, Это не безопасно, в том смысле, что можно получить значение, которое / быть обновленным другим потоком.
"Атомарный" означает, что Вы получаете вторую гарантию. С тех пор дважды обычно не является атомарным, Вы могли получить 32 старых и 32 новых бита. Это явно небезопасно.
Когда я задал вопрос я наиболее интересующийся унипроцессором powerpc. В одном из комментариев InSciTek Jeff упомянул СИНХРОНИЗАЦИЮ powerpc и инструкции ISYNC. Те, где ключ к категорическому ответу. Я нашел его здесь на сайте IBM.
статья является большой и довольно плотной, но устранение нет, это не безопасно. На более старом powerpc's оптимизаторы памяти, где не достаточно сложный для порождения проблем на унипроцессоре. Однако более новые намного более агрессивны, и могут стать безубыточным простой доступ к глобальному интервалу