Как я захватываю Type
из наследованного класса и передачи это в основного конструктора класса, также наследованного? См. пример кода ниже:
// VeryBaseClass is in an external assembly
public abstract class VeryBaseClass
{
public VeryBaseClass(string className, MyObject myObject)
{
}
}
// BaseClass and InheritedClass are in my assembly
public abstract class BaseClass : VeryBaseClass
{
public BaseClass(MyObject myObject) :
base(this.GetType().Name, myObject) // can't reference "this" (Type expected)
{
}
}
public class InheritedClass : BaseClass
{
public InheritedClass(MyObject myObject)
{
}
}
Строка base(typeof(this).Name, myObject)
не работает, потому что я не могу сослаться this
все же, поскольку объект не закончил создавать и поэтому не существует.
Действительно ли возможно захватить Type
из в настоящее время создающего объекта?
Править:
Исправленный образец как orsogufo предложенный, но все еще не работает, как this
не определено.
РЕДАКТИРОВАНИЕ 2:
Просто для уточнения я хочу закончить с "InheritedClass"
быть переданным в VeryBaseClass(string className, MyObject myObject)
конструктор.
А Ха! Я нашел решение. Вы можете сделать это с помощью дженериков:
public abstract class VeryBaseClass
{
public VeryBaseClass(string className, MyObject myObject)
{
this.ClassName = className;
}
public string ClassName{ get; set; }
}
public abstract class BaseClass<T> : VeryBaseClass
{
public BaseClass(MyObject myObject)
: base(typeof(T).Name, myObject)
{
}
}
public class InheritedClass : BaseClass<InheritedClass>
{
public InheritedClass(MyObject myObject)
: base(myObject)
{
}
}
Возможное решение:
class VeryBase {
public VeryBase(string name) {
Console.WriteLine(name);
}
}
class Base<T> : VeryBase where T : Base<T> {
protected Base()
: base(typeof(T).Name) {
}
}
class Derived : Base<Derived> {
public Derived() {
}
}
class Program {
public static void Main(params string[] args) {
Derived d = new Derived();
}
}
Не сдавайтесь. Оружие, которое вы можете использовать, чтобы убедить ваших клиентов в негодности. Если вы можете восстановить пароли пользователей с помощью любого механизма, вы предоставили их клиентам законный механизм отказа от регистрации, и они могут отказаться от любой транзакции, которая зависит от этого пароля, потому что нет пути, что поставщик может доказать, что они не восстановили пароль и провести транзакцию через себя. Если пароли правильно хранятся в виде дайджестов, а не шифротекста, это невозможно, эрго либо конечный клиент выполнил транзакцию сам, либо нарушил свою обязанность по уходу w.r.t. пароль. В любом случае, что оставляет ответственность прямо с ним. Я работал над случаями, когда это составляло бы сотни миллионов долларов. Не то, что ты хочешь ошибиться.
-121--1751563- См. этот связанный вопрос . Необходимо нарисовать собственный прямоугольник на CGPath
с некоторыми скругленными углами, добавить CGPath
в CGContext
и затем подрезать его с помощью CGConTextClip
.
Можно также нарисовать округленную прямую с альфа-значениями для изображения, а затем использовать это изображение для создания нового слоя, который был задан как свойство mask
слоя ( см. документацию Apple ).
Я испытывал такую же боль в Google Wave Robot .NET API , где я хотел, чтобы конструктор передавал некоторые значения на основе атрибутов. Можно просмотреть мое решение в коде для производного типа и базового типа . В основном я передаю делегата базовому конструктору, а затем вызываю делегата, проходящего «это». Так что в вашем случае у вас было бы:
public VeryBaseClass(Func<VeryBaseClass, string> classNameProvider)
{
this.name = classNameProvider(this);
}
и
public BaseClass() : base(FindClassName)
{
}
private static string FindClassName(VeryBaseClass @this)
{
return @this.GetType().Name;
}
Это действительно уродливо, но это работает.
EDIT: Этот подход работает только в том случае, если можно изменить конструктор базового класса, как показано на рисунке; если вы не можете, я не уверен, что это вообще возможно: (
Еще один вариант ...
// VeryBaseClass is in an external assembly
public abstract class VeryBaseClass
{
public VeryBaseClass(string className)
{
Console.WriteLine(className);
}
}
// BaseClass and InheritedClass are in my assembly
public abstract class BaseClass : VeryBaseClass
{
public BaseClass(string className)
:
base(className)
{
}
}
public class InheritedClass : BaseClass
{
public InheritedClass()
: base(typeof(InheritedClass).Name)
{
}
}
Если способность определять тип унаследованного класса во время выполнения более важна, чем производительность, вы можете взглянуть на StackTrace, чтобы увидеть, где вызывается конструктор из. При вызове GetInheritedClassName в этом примере вам может потребоваться ввести больше допущений:
public abstract class BaseClass : VeryBaseClass
{
private static string GetInheritedClassName
{
get
{
// Get the current Stack
StackTrace currentStack = new StackTrace();
MethodBase method = currentStack.GetFrame(1).GetMethod();
// 1st frame should be the constructor calling
if (method.Name != ".ctor")
return null;
method = currentStack.GetFrame(2).GetMethod();
// 2nd frame should be the constructor of the inherited class
if (method.Name != ".ctor")
return null;
// return the type of the inherited class
return method.ReflectedType.Name;
}
}
public BaseClass(MyObject myObject) :
base(GetInheritedClassName, myObject)
{
}
}
Я не могу придумать отличный способ динамического получения имени унаследованного класса без последствий для производительности. Я понимаю, что это то, чего вы хотели избежать, но если бы мне нужно было вызвать стороннюю сборку с этими требованиями, я бы просто потребовал, чтобы каждый класс указывал свой собственный тип:
public abstract class BaseClass : VeryBaseClass
{
public BaseClass(string className, MyObject myObject) :
base(className, myObject)
{
}
}
public class InheritedClass : BaseClass
{
public InheritedClass(MyObject myObject) : base("InheritedClass", myObject)
{
}
}