Вот почему динамически созданные элементы не реагируют на клики & nbsp;:
var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
console.log(this);
});
// Too late for `<button>B</button>`...
body.append(btnB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>
В качестве обходного пути вы должны прослушивать все клики и проверять исходный элемент & nbsp;:
var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
if ($(ev.target).is("button")) {
console.log(ev.target);
}
});
// Now you can add any number
// of `<button></button>`.
body.append(btnB);
body.append(btnC);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>
Это называется «Event Delegation». Хорошие новости, это встроенная функция в jQuery: -)
var i = 11;
var body = $("body");
body.on("click", "button", function () {
var letter = (i++).toString(36).toUpperCase();
body.append($("<button>" + letter + "</button>"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>
Хотя следующий ответ делает то, что вы хотите, на самом деле нет смысла, потому что это просто ненужно. Если вам нужно указать свойство, вы можете просто установить его напрямую.
Здесь, наверное, как можно ближе. Я не верю, что вы можете использовать params
, потому что для этого потребуется, чтобы все TProp
были одного типа.
В Visual Studio, когда вы перейдете к периоду, вы получите intellisense:
using System;
using System.Linq.Expressions;
using System.Reflection;
public class Program
{
public static void Main()
{
var orderDto = new OrderDto
{
Id = 1,
Name = "Name",
CreatedOn = DateTime.UtcNow,
CompletedOn = DateTime.UtcNow.AddMinutes(30),
Misc = Guid.NewGuid()
};
Console.WriteLine($"{orderDto.Id} {orderDto.Name} {orderDto.CreatedOn} {orderDto.CompletedOn} {orderDto.Misc}");
orderDto.DefaultFor(x => x.Id, x => x.Name, x => x.CreatedOn, x => x.CompletedOn);
Console.WriteLine($"{orderDto.Id} {orderDto.Name} {orderDto.CreatedOn} {orderDto.CompletedOn} {orderDto.Misc}");
}
}
public static class ObjectExtensions
{
public static void DefaultFor<TObject, TProp1, TProp2, TProp3, TProp4>(this TObject instance,
Expression<Func<TObject, TProp1>> selector1,
Expression<Func<TObject, TProp2>> selector2,
Expression<Func<TObject, TProp3>> selector3,
Expression<Func<TObject, TProp4>> selector4)
where TObject : class
{
DefaultFor(instance, selector1, selector2, selector3);
DefaultFor(instance, selector4);
}
public static void DefaultFor<TObject, TProp1, TProp2, TProp3>(this TObject instance,
Expression<Func<TObject, TProp1>> selector1,
Expression<Func<TObject, TProp2>> selector2,
Expression<Func<TObject, TProp3>> selector3)
where TObject : class
{
DefaultFor(instance, selector1, selector2);
DefaultFor(instance, selector3);
}
public static void DefaultFor<TObject, TProp1, TProp2>(this TObject instance,
Expression<Func<TObject, TProp1>> selector1,
Expression<Func<TObject, TProp2>> selector2)
where TObject : class
{
DefaultFor(instance, selector1);
DefaultFor(instance, selector2);
}
public static void DefaultFor<TObject, TProp>(this TObject instance, Expression<Func<TObject, TProp>> selector)
where TObject : class
{
if (instance == null)
throw new ArgumentNullException();
var memberExpression = (MemberExpression)selector.Body;
var property = (PropertyInfo)memberExpression.Member;
property.SetValue(instance, default(TProp));
}
}
public class OrderDto
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? CompletedOn { get; set; }
public Guid Misc { get; set; }
}
Вывод:
1 Имя 29.03.2009 5:14:06 3/29/2019 5:44:06 3800be41-7fe1-42da -ada5-4fe33ac04a84
0 1/1/0001 12:00:00 AM 3800be41-7fe1-42da-ada5-4fe33ac04a84
blockquote>
Перефразируя немного:
// Я хочу, чтобы список автозаполнения в Visual Studio сообщал программисту, какие свойства T доступны
blockquote>Проблема типа
T
может быть что угодно . Вы должны иметь возможность использовать этот код в совершенно другой сборке, когда ни Visual Studio, ни компилятор не знают о вашемT
во время компиляции.Я не скажу, что это невозможно. Visual Studio очень расширяема, особенно сейчас у нас есть Roslyn . Но это то, что вам нужно сделать: пользовательское расширение Visual Studio, использующее Roslyn для анализа кода и предоставления списка завершения. Это не встроено в платформу.