В зависимости от вашей конкретной цели существует способ достижения полезности родительского селектора без использования одного (даже если бы он существовал) ...
Скажем, у нас есть:
<div>
<ul>
<li><a>Pants</a></li>
<li><a>Socks</a></li>
<ul>
<li><a>White socks</a></li>
<li><a>Blue socks</a></li>
</ul>
</ul>
</div>
Что мы можем сделать, чтобы блок Socks (включая цвета носка) выделялся визуально с использованием интервала?
Что было бы неплохо, но не существует:
ul li ul:parent {
margin-top: 15px;
margin-bottom: 15px;
}
Что существует:
li > a {
margin-top: 15px;
display: block;
}
li > a:only-child {
margin-top: 0px;
}
Это устанавливает, что все привязные ссылки имеют верхний край 15px и сбрасывают его обратно на 0 для тех, у которых нет элементов UL (или других тегов) внутри LI.
Нет, CLR не позволяет привязывать делегатов к ConstructorInfo
.
Однако вы можете просто создать свой собственный:
static T Make<T>(Action<T> init) where T : new()
{
var t = new T();
init(t);
return t;
}
Использование
var t = Make<Foo>( x => { x.Bar = "bar"; x.Baz = 1; });
Другая опция состояла бы в том, чтобы использовать Activator
класс, как так:
Используя Универсальные Типы
public delegate Foo FooGeneratorDelegate<T>(int x);
public T FooGeneratorFunction<T>(int x)
{
return (T)Activator.CreateInstance(typeof(T), x);
}
// implementation example
FooGeneratorDelegate<Foo> del = FooGeneratorFunction<Foo>;
Foo foo = del(someIntValue);
Передача Вашего Нечто Типа в качестве параметра
public delegate object FooGeneratorDelegate(Type t, int x);
public object FooGeneratorFunction(Type t, int x)
{
return Activator.CreateInstance(t, x);
}
// implementation example
FooGeneratorDelegate del = FooGeneratorFunction;
Foo foo = (Foo)del(typeof(Foo), someIntValue);
, Если Тип будет Всегда иметь Тип Foo
public delegate Foo FooGeneratorDelegate(int x);
public Foo FooGeneratorFunction(int x)
{
return (Foo)Activator.CreateInstance(typeof(Foo), x);
}
// implementation example
FooGeneratorDelegate del = FooGeneratorFunction;
Foo foo = del(someIntValue);
Я думаю, что настолько кратким, насколько вы собираетесь получить (без перехода к заводскому шаблону), было бы что-то с анонимными методами, например:
delegate Foo FooGenerator(int x);
...
void DoStuff()
{
YourDelegateConsumer(x => new Foo(x));
}
Это не делает строго то, что вы запрашивается (поскольку вы передаете делегата анонимному методу, который возвращает новый экземпляр, а не прямому делегату конструктору), но я не думаю, что то, что вы просите, строго возможно.
Это конечно при условии, что вы используете 3.5+
Похоже, вы, вероятно, захотите использовать шаблон фабрики классов.
К сожалению, нет, конструкторы - это не совсем то же самое, что методы, и поэтому вы не можете создать делегат, указывающий на них. Это интересная идея, возможно, имея больше информации, мы могли бы разработать какой-то обходной путь, который был бы синтаксически похожим.
Я предполагаю, что это не Это возможно, так как вы должны передать метод объекта, который еще не был создан.
Я предполагаю, что вы обычно делаете что-то подобное в рамках реализации фабрики, где фактические типы не известны во время компиляции ...
Во-первых, обратите внимание, что более простым подходом может быть этап инициализации после создания, тогда вы можете использовать универсальные шаблоны:
static T Create<T>({args}) where T : class, ISomeInitInterface, new() {
T t = new T();
t.Init(args);
return t;
}
Затем вы можете использовать MakeGenericMethod
и / или CreateDelegate
.
В противном случае; вы можете сделать это «на лету» с помощью Expression
(3.5) или DynamicMethod
(2.0).
Подход Expression
проще закодировать:
var param = Expression.Parameter(typeof(int), "val");
var ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
var lambda = Expression.Lambda<Func<int, Foo>>(
Expression.New(ctor, param), param);
var func = lambda.Compile();
Foo foo = func(123);
string s = foo.ToString(); // proof
или (используя DynamicMethod
):
ConstructorInfo ctor = typeof(Foo).GetConstructor(new[] { typeof(int) });
DynamicMethod dm = new DynamicMethod("Create", typeof(Foo),
new Type[] { typeof(int) }, typeof(Foo), true);
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
Converter<int, Foo> func = (Converter<int, Foo>)
dm.CreateDelegate(typeof(Converter<int, Foo>));
Foo foo = func(123);
string s = foo.ToString(); // proof