.NET. Определите тип этого «classа» в статическом методе
В this.GetType()
методе я мог бы использовать this.GetType()
и он вернет Type
. Как я могу получить один и тот же Type
в статическом методе? Конечно, я не могу просто написать typeof(ThisTypeName)
потому что ThisTypeName
известен только во время выполнения. Благодаря!
- Есть ли способ отключить перегрузку функций в Postgres
- Когда целесообразно использовать связанный тип по сравнению с общим типом?
- Как запросить json-столбец для пустых объектов?
- Тип аргумента для сигнала и слота Qt, имеет ли значение задание отступников?
- В чем разница между 'int?' и 'int' в C #?
- Почему эти уравнения деления приводят к нулю?
- Вычисление переменной с использованием переменной типа
- Какой примитивный тип данных - time_t?
Если вы ищете 1 лайнер, эквивалентный этому. this.GetType()
для статических методов, попробуйте следующее.
Type t = MethodBase.GetCurrentMethod().DeclaringType
Хотя это, вероятно, намного дороже, чем просто использование typeof(TheTypeName)
.
Есть кое-что, что другие ответы не совсем понятны, и что имеет отношение к вашей идее того, что тип доступен только во время выполнения.
Если вы используете производный тип для выполнения статического члена, имя реального типа не указывается в двоичном формате. Так, например, скомпилируйте этот код:
UnicodeEncoding.GetEncoding(0);
Теперь используйте ildasm на нем … вы увидите, что звонок вызывается следующим образом:
IL_0002: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::GetEncoding(int32)
Компилятор разрешил вызов Encoding.GetEncoding
– нет следов UnicodeEncoding
влево. Я боюсь, что ваше представление о «текущем типе» бессмысленно.
Другим решением является использование типа самообучения
//My base class //I add a type to my base class use that in the static method to check the type of the caller. public class Parent { public static Type GetType() { return typeof(TSelfReferenceType); } }
Затем в classе, который наследует его, я создаю тип реферирования:
public class Child: Parent { }
Теперь тип вызова typeof (TSelfReferenceType) внутри Parent будет получать и возвращать Тип вызывающего абонента без необходимости экземпляра.
Child.GetType();
Роб
Вы не можете использовать this
в статическом методе, так что это невозможно напрямую. Однако, если вам нужен тип какого-либо объекта, просто вызовите GetType
на нем и сделайте this
экземпляр параметром, который вы должны передать, например:
public class Car { public static void Drive(Car c) { Console.WriteLine("Driving a {0}", c.GetType()); } }
Это похоже на плохой дизайн. Вы уверены, что вам действительно нужно получить тип самого экземпляра внутри своего собственного статического метода? Это кажется немного странным. Почему бы просто не использовать метод экземпляра?
public class Car { public void Drive() { // Remove parameter; doesn't need to be static. Console.WriteLine("Driving a {0}", this.GetType()); } }
Я не понимаю, почему вы не можете использовать typeof (ThisTypeName). Если это не общий тип, то это должно работать:
class Foo { static void Method1 () { Type t = typeof (Foo); // Can just hard code this } }
Если это общий тип, то:
class Foo { static void Method1 () { Type t = typeof (Foo ); } }
Я пропустил что-то очевидное здесь?
Когда ваш член статичен, вы всегда будете знать, какой тип он является частью во время выполнения. В этом случае:
class A { public static int GetInt(){} } class B : A {}
Вы не можете позвонить (отредактируйте: видимо, вы можете, см. Комментарий ниже, но вы все равно будете звонить в A):
B.GetInt();
поскольку элемент статичен, он не играет роли в сценариях наследования. Эрго, вы всегда знаете, что тип A.
Для моих целей мне нравится идея @ T-moty. Несмотря на то, что я использовал информацию типа «self-referencing type» в течение многих лет, ссылка на базовый class сложнее сделать позже.
Например (используя пример @Rob Leclerc сверху):
public class ChildA: Parent { } public class ChildB: Parent { }
Например, работа с этим шаблоном может быть сложной задачей; как вы возвращаете базовый class из вызова функции?
public Parent GetParent() {}
Или при типе литья?
var c = (Parent) GetSomeParent();
Поэтому я стараюсь избегать этого, когда могу, и использовать его, когда должен. Если вам нужно, я предлагаю вам следовать этому шаблону:
class BaseClass { // All non-derived class methods goes here... // For example: public int Id { get; private set; } public string Name { get; private set; } public void Run() {} } class BaseClass : BaseClass { // All derived class methods goes here... // For example: public TSelfReferenceType Foo() {} public void Bar(TSelfRefenceType obj) {} }
Теперь вы можете (более) легко работать с BaseClass
. Тем не менее, бывают моменты, например, моя текущая ситуация, когда разоблачение производного classа изнутри базового classа не требуется, и использование предложения @ M-moty просто может быть правильным подходом.
Однако использование кода @ M-moty работает только до тех пор, пока базовый class не содержит конструкторов экземпляров в стеке вызовов. К сожалению, мои базовые classы используют конструкторы экземпляров.
Таким образом, вот мой метод расширения, который учитывает конструкторы «instance» базового classа:
public static class TypeExtensions { public static Type GetDrivedType(this Type type, int maxSearchDepth = 10) { if (maxSearchDepth < 0) throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0."); const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor. var stack = new StackTrace(); var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount); var frame = skipFrames; // Skip all the base class 'instance' ctor calls. // while (frame < maxCount) { var method = stack.GetFrame(frame).GetMethod(); var declaringType = method.DeclaringType; if (type.IsAssignableFrom(declaringType)) return declaringType; frame++; } return null; } }
EDIT. Эти методы будут работать только при развертывании файлов PDB с исполняемым файлом / библиотекой, как отметил мне markmnl .
В противном случае будет огромная проблема, которая будет обнаружена: хорошо работает в разработке, но, возможно, не в производстве.
Утилита, просто вызовите метод, когда вам нужно, со всего места вашего кода:
public static Type GetType() { var stack = new System.Diagnostics.StackTrace(); if (stack.FrameCount < 2) return null; return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType; }