Рейтинг:
1
________________
string dotNetClass = "";
string dotNet = dotNetClass.GetType().Assembly.FullName;
Это дает ""mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Member 13580583
Это не то, что я ищу.
Пожалуйста, посмотрите мой код, и вы получите представление о том, чего я ожидаю.
________________
Взгляните на это https://www.codeproject.com/Articles/827091/Csharp-Attributes-in-minutes
.NET имеет современные инструменты (а не только препроцессор). Если вам нужно что - то вычислить на этапе компиляции- используйте атрибуты.
Member 13580583
Спасибо за помощь, но мое требование не так уж сложно, это простая программа, которая, если она скомпилирована в net standard(или определен символ компиляции), возвращает NETSTANDARD, а если в Net Framework, то возвращает NETFRAMEWORK.
Я понимаю атрибуты, но все равно предпочитаю #ifdefs.
Member 13580583
Если тип проекта-библиотека Net Standard, то в свойствах проекта вы получаете заранее определенный символ компиляции NETSTANDARD2_0.
________________
Компилятору нужен случай, если ничего не определено:
публичная статическая строка FooImpl()
{
#если NETSTANDARD2_0
возврат "NETSTANDARD";
#elif NET461
return "NETFRAMEWORK";
#endif
вернуть "";
}
Member 13580583
Да, я пропустил это. Но у меня другой вопрос.
Так или иначе, я получил ответ.
В любом случае, спасибо.
Richard Deeming
Это было бы более эффективно использовать typeof(string).Assembly.FullName
; зовущий Object.GetType
он печально известен своей медлительностью.
________________
Нет, вы ошибаетесь... согласитесь, что это странно - typeof(string) выглядит как "низкоуровневая" языковая команда, но:
typeof(строка).Собрание.Полное имя -> 901
Объект.GetType -> 899
typeof(строка).Собрание.Полное имя -> 1765
Объект.GetType -> 871
Код теста :
Тест секундомера = новый секундомер();
тест.Начать();
for (int i = 0; i < 10000; i++)
{
string dll_Name = typeof(строка).Собрание.Полное имя;
}
тест.Стоп();
Приставка.WriteLine(строка.Формат("typeof(string).Собрание.Полное имя -> {0}", тест.ElapsedTicks));
тест.Сброс();
струнное ООО = "";
тест.Начать();
for (int i = 0; i < 10000; i++)
{
строки имя_dll = ООО.Метод gettype().Сборка.Полное имя;
}
тест.Стоп();
Приставка.WriteLine(строка.Формат("Объект.GetType -> {0}", тест.ElapsedTicks));
тест.Начать();
for (int i = 0; i < 10000; i++)
{
string dll_Name = typeof(строка).Собрание.Полное имя;
}
тест.Стоп();
Приставка.WriteLine(строка.Формат("typeof(string).Собрание.Полное имя -> {0}", тест.ElapsedTicks));
тест.Сброс();
тест.Начать();
for (int i = 0; i < 10000; i++)
{
строки имя_dll = ООО.Метод gettype().Сборка.Полное имя;
}
тест.Стоп();
Приставка.WriteLine(строка.Формат("Объект.GetType -> {0}", тест.ElapsedTicks));
Richard Deeming
Я вижу противоположный результат, используя BenchmarkDotNet[^]:
public class TypeInfoBenchmark
{
[Benchmark]
public Type WithTypeOf()
{
return typeof(string);
}
[Benchmark]
public Type WithGetType()
{
return string.Empty.GetType();
}
}
BenchmarkRunner.Run<TypeInfoBenchmark>();
Результаты:
Method | Mean | StdDev |
------------ |---------- |---------- |
WithTypeOf | 0.9272 ns | 0.0044 ns |
WithGetType | 2.3251 ns | 0.0441 ns |
________________
Хех, в прошлый раз огромное количество "фреймворков" было разработано только для того, чтобы продать его и получить прибыль...
Я предпочитаю использовать низкоуровневые инструменты, когда это возможно, и каждое приложение имеет ошибки...
Отправьте это дело разработчикам бенчмарков. :-)
________________
typeof(строка).Собрание.Полное имя -> 446
Объект.GetType -> 351
с помощью этого кода (аналогичного вашему):
public static void Test1()
{
Stopwatch test = new Stopwatch();
test.Start();
typeof_string();
test.Stop();
Console.WriteLine(string.Format("typeof(string).Assembly.FullName -> {0}", test.ElapsedTicks));
test.Reset();
test.Start();
GetType_FullName();
test.Stop();
Console.WriteLine(string.Format("Object.GetType -> {0}", test.ElapsedTicks));
}
private static string typeof_string()
{
return typeof(string).Assembly.FullName;
}
private static string GetType_FullName()
{
return String.Empty.GetType().Assembly.FullName;
}
Что я должен думать? Ядро .Объем секундомера не так, сторонние чудо "рамки" - это правильно?
Richard Deeming
BenchmarkDotNet является бесплатным и открытым исходным кодом. Он не пытается вам что-то продать. :)
Richard Deeming
Бенчмаркинг кода - это сложный процесс, особенно когда вы пытаетесь сравнить отдельные операторы, подобные этому.
Вам нужно разогреть код, чтобы убедиться, что JIT-компиляция не влияет на результаты. Вам нужно компилировать в режиме выпуска, с включенной оптимизацией. Вы должны убедиться, что JIT-компилятор не решит удалить код, который вы тестируете, потому что результат не используется. Вам нужно выполнить тест много раз в цикле, чтобы получить среднее время.
Обо всем этом BenchmarkDotNet позаботится за вас.
Richard Deeming
Небольшая модификация вашего кода:
public static void Test1()
{
string s1 = typeof_string();
string s2 = GetType_FullName();
const int iterations = 1000000;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
string s3 = typeof_string();
if (s3 != s1) throw new InvalidOperationException();
}
sw.Stop();
Console.WriteLine("typeof(string).Assembly.FullName -> {0}", sw.ElapsedTicks);
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; i++)
{
string s3 = GetType_FullName();
if (s3 != s2) throw new InvalidOperationException();
}
sw.Stop();
Console.WriteLine("Object.GetType -> {0}", sw.ElapsedTicks);
}
private static string typeof_string()
{
return typeof(string).Assembly.FullName;
}
private static string GetType_FullName()
{
return String.Empty.GetType().Assembly.FullName;
}
Запуск этого в LINQPad с включенной оптимизацией дает результаты:
typeof(string).Assembly.FullName -> 64904
Object.GetType -> 67988
С отключенной оптимизацией:
typeof(string).Assembly.FullName -> 99869
Object.GetType -> 98907
В обоих случаях,
typeof(string)
выигрывает, хотя и с небольшим отрывом.
________________
если (s3 != s1) выбросить новое исключение InvalidOperationException(); - ??????
Ты серьезно? Почему бы не нить.Сон(100)? с этим дополнением вы увидите абсолютно равные результаты!
:-))))))))))))
Richard Deeming
Потому что если вы не используете возвращаемое значение, существует опасность, что компилятор C# или JIT-компилятор решит оптимизировать код, удалив вызов, который вы пытаетесь протестировать.
Если это произойдет, то вы определенно получите одинаковые результаты для обоих.
Вот почему я добавил одно и то же утверждение в оба цикла. Это не влияет на относительное время, так как оно одинаково для обоих; но это гарантирует, что результат метода будет использован.
Существует множество подводных камней, которых следует избегать при бенчмаркинге кода. Вот почему большинство из нас использует такую библиотеку, как BenchmarkDotNet, которая заботится об этих вещах для вас.