В конечном счете необходимо изучить обоих. Но STL может быть изучен в изоляции, тогда как повышение не будет иметь большого смысла, пока Вы не поймете STL, так как это - то, какое Повышение смоделировано на и разработано для расширения. Поэтому учитесь использовать STL в качестве части изучения C++. И затем можно идти дальше для Повышения, который является более или менее "второй стандартной библиотекой" в эти дни.
Это наблюдение было опубликовано на StackOverflow в другом вопросе ранее сегодня.
Отличный ответ Марка на этот вопрос указывает на то, что согласно спецификации (раздел 7.5.7), вы не должны иметь доступ к this
в том контекст и возможность сделать это в компиляторе C # 3.0 является ошибкой. Компилятор C # 4.0 ведет себя правильно в соответствии со спецификацией (даже в Beta 1 это ошибка времени компиляции):
§ 7.5.7 Этот доступ
A this-access состоит из зарезервированных word
this
.this-access:
this
this-access разрешен только в блоке конструктора экземпляра, метода экземпляра или метода доступа к экземпляру.
Я могу ошибаться, но я почти уверен, что если ваш объект null
, то никогда не будет сценария, в котором это
применимо.
Например, как бы вы могли вызвать CheckNull
?
Derived derived = null;
Console.WriteLine(derived.CheckNull()); // this should throw a NullReferenceException
Необработанная декомпиляция (отражатель без оптимизаций) двоичного файла режима отладки:
private class Derived : Program.Base
{
// Methods
public Derived()
{
base..ctor(new Func<string>(Program.Derived.<.ctor>b__0));
return;
}
[CompilerGenerated]
private static string <.ctor>b__0()
{
string CS$1$0000;
CS$1$0000 = CS$1$0000.CheckNull();
Label_0009:
return CS$1$0000;
}
private string CheckNull()
{
string CS$1$0000;
CS$1$0000 = "Am I null? " + ((bool) (this == null));
Label_0017:
return CS$1$0000;
}
}
Метод CompilerGenerated не имеет смысла; если вы посмотрите на IL (ниже), он вызывает метод для нулевой строки (!).
.locals init (
[0] string CS$1$0000)
L_0000: ldloc.0
L_0001: call instance string CompilerBug.Program/Derived::CheckNull()
L_0006: stloc.0
L_0007: br.s L_0009
L_0009: ldloc.0
L_000a: ret
В режиме Release локальная переменная оптимизирована, поэтому она пытается протолкнуть не- существующая переменная в стеке.
L_0000: ldloc.0
L_0001: call instance string CompilerBug.Program/Derived::CheckNull()
L_0006: ret
(Отражатель аварийно завершает работу при преобразовании его в C #)
РЕДАКТИРОВАТЬ : Кто-нибудь (Эрик Липперт?) знает, почему компилятор выдает ldloc
?
Это не «ошибка». Это вы злоупотребляете системой типов. Вы никогда не должны передавать ссылку на текущий экземпляр ( this
) кому-либо в конструкторе.
Я мог бы создать аналогичную «ошибку», вызвав виртуальный метод в конструкторе базового класса.
То, что вы можете сделать что-то плохое, не означает, что это ошибка , когда тебя укусит.
Не уверен, что это то, что вы ищете
public static T CheckForNull<T>(object primary, T Default)
{
try
{
if (primary != null && !(primary is DBNull))
return (T)Convert.ChangeType(primary, typeof(T));
else if (Default.GetType() == typeof(T))
return Default;
}
catch (Exception e)
{
throw new Exception("C:CFN.1 - " + e.Message + "Unexpected object type of " + primary.GetType().ToString() + " instead of " + typeof(T).ToString());
}
return default(T);
}
пример: UserID = CheckForNull(Request.QueryString["UserID"], 147);