Может быть ниже кода справки Я использую jquery:
<table id="tableId">
<tr>
<td align="center"><input type="checkbox" name="chkToPay" value="0"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="1"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="2"></td>
<td align="center"><input type="checkbox" name="chkToPay" value="3"></td>
</tr>
$(document).on("click", '#tableId tbody :checkbox[name="chkToPay"]', function(event) {
var currentRows = $('#tableId');
$.each(currentRows, function() {
$(this).find(':checkbox[name=chkToPay]').each(function() {
if($(this). prop("checked") == true){
var parentTr = $(this).parents("tr");
$(this).prop('checked', true);
alert($(this).val());
// if you need text from another td you can access by below line
//alert(parentTr.children("td").eq(0).text());
}
});
});
});
ИМХО, он не используется, потому что:
Новый класс Lazy в .net 4.0
обеспечивает поддержку нескольких распространенных шаблонов ленивой инициализации
По моему опыту, это самая распространенная причина, по которой я хочу правильно оберните поле в приват, так что хорошо решает общий случай. (Если вы еще не используете .Net 4, вы можете просто создать свой собственный класс «Lazy» с тем же API, что и в версии .Net 4.)
См. , это и . это и это для деталей использования класса Lazy.
Если вы используете компилятор C # 3.0, вы можете определить свойства, которые имеют сгенерированные компилятором вспомогательные поля, например:
public int MyInt { get; set; }
Это будет означать, что есть только один способ доступа к свойству. не означает, что вы можете получить доступ только к полю, но это означает, что нет ничего, кроме свойства для доступа.
Вы говорите, что делаете дополнительную обработку. Предположительно это можно было бы обнаружить при правильных условиях. Тогда я решил бы создать модульные тесты, в которых реализованы такие условия, что, если поле поддержки используется напрямую, тест не пройден. Используя эти тесты, вы сможете убедиться, что ваш код правильно использует интерфейс свойств, пока тесты пройдут.
Это имеет то преимущество, что вам не нужно ставить под угрозу свой дизайн. Вы получаете безопасность модульных тестов, чтобы убедиться, что вы случайно не вносите критические изменения, и вы понимаете, как работает класс, чтобы другие, пришедшие позже, могли прочитать ваши тесты как «документацию».
Это невозможно сделать в стандартном C #, однако вы можете
определить пользовательский атрибут, например, OnlyAccessFromProperty
написать свой код. как
[OnlyAccessFromProperty(Name)]
String name
Name
{
get{return name;}
}
etc …
Затем напишите пользовательское правило для FxCop
(или другого средства проверки)
Добавьте FxCop
в свою систему сборки поэтому, если ваше пользовательское правило обнаружит ошибку, сборка будет неудачной.
Нужен ли нам набор стандартных настраиваемых правил / атрибутов для реализации таких патентов общего дизайна без необходимости расширять C #
Возможно, хранилище резервных копий свойств аналогично тому, как WPF хранит свойства ?
. Таким образом, вы можете иметь:
Dictionary<string,object> mPropertyBackingStore = new Dictionary<string,object> ();
public PropertyThing MyPropertyThing
{
get { return mPropertyBackingStore["MyPropertyThing"] as PropertyThing; }
set { mPropertyBackingStore["MyPropertyThing"] = value; }
}
. - обработка, которую вы хотите сейчас, безопасная, зная, что если бы кто-то действительно обращался к переменной напрямую, это было бы действительно очень сложно по сравнению со средством доступа к свойствам.
P.S. Вы даже можете использовать инфраструктуру свойств зависимостей из WPF ...
P.P.S. Очевидно, что это повлечет за собой затраты на кастинг, но это зависит от ваших потребностей - если производительность критична, возможно, это не решение для вас.
P.P.P.S Не забудьте инициализировать резервное хранилище! (;
РЕДАКТИРОВАТЬ:
Фактически, если вы измените свойство значения, сохраненное на объект хранения свойства (например, с помощью шаблона Command)), вы можете обработка в объекте команды ... просто мысль.
Вы можете поместить все свои личные поля во вложенный класс и открыть их через открытые свойства. Затем в вашем классе вы создаете экземпляр этого вложенного класса и используете его. Таким образом, эти частные поля не будут доступны, как если бы они были частью вашего основного класса.
public class A
{
class FieldsForA
{
private int number;
public int Number
{
get
{
//TODO: Extra logic.
return number;
}
set
{
//TODO: Extra logic.
number = value;
}
}
}
FieldsForA fields = new FieldsForA();
public int Number
{
get{ return fields.Number;}
set{ fields.Number = value;}
}
}
Это просто обеспечивает уровень обструкции. Основная проблема доступа к частным резервным полям все еще существует во вложенном классе. Однако код в классе A не может получить доступ к этим закрытым полям вложенного класса FieldForA. Он должен пройти через общественную собственность.
В C # такого обеспечения нет.
Однако я бы назвал закрытые переменные по-разному (например, m_something или просто _something), чтобы легче было определить его при использовании.
Вы МОЖЕТЕ сделать это, используя замыкание над локальным в конструкторе (или другой функцией инициализации). Но это требует значительно больше работы, чем подход вспомогательного класса .
class MyClass {
private Func<Foo> reallyPrivateFieldGetter;
private Action<Foo> reallyPrivateFieldSetter;
private Foo ReallyPrivateBackingFieldProperty {
get { return reallyPrivateFieldGetter(); }
set { reallyPrivateFieldSetter(value); }
}
public MyClass() {
Foo reallyPrivateField = 0;
reallyPrivateFieldGetter = () => { return reallyPrivateField; }
reallyPrivateFieldSetter = v => { reallyPrivateField = v; };
}
}
Я подозреваю, что базовый тип поля Foo
должен быть эталонным классом, поэтому два замыкания создаются для одного объекта.
Нет встроенного способа делать то, что вы хотите делать, но по звукам вещей вам нужен еще один уровень абстракции между вашим классом и этим значением.
Создайте отдельный класс и поместите туда элемент, тогда ваш внешний класс содержит новый класс, и вы можете получить к нему доступ только через его свойства.
Я бы посчитал это мерзким взломом и попытался бы избежать его, если это возможно, но ...
Вы можете пометить вспомогательное поле как устаревшее, чтобы компилятор генерировал предупреждение при попытке доступа к нему, а затем подавляло это предупреждение для свойства getter / setter.
Коды предупреждений, которые вам нужно подавить: CS0612 для простого атрибута Obsolete
и CS0618 , если у атрибута есть пользовательское сообщение.
[Obsolete("Please don't touch the backing field!")]
private int _backingField;
public int YourProperty
{
#pragma warning disable 612, 618
get { return _backingField; }
set { _backingField = value; }
#pragma warning restore 612, 618
}
В C # нет языковой функции для этого. Однако вы можете полагаться на соглашения об именах, аналогичные языкам, которые вообще не имеют частных свойств. Добавьте к своим более частным именам переменных префикс _p_
, и вы будете совершенно уверены, что случайно не наберете его.
Используйте тип конструкции «очень конфиденциальный»
Пример:
veryprivate void YourMethod()
{
// code here
}
Я согласен с общим правилом что класс должен доверять себе (и, следовательно, всем, кто кодирует внутри класса).
Жалко, что поле раскрывается через интеллект.
К сожалению, размещение [EditorBrowsable (EditorBrowsableState.Never)]
не работает в этом классе (или действительно в сборке (1))
В Visual C # EditorBrowsableAttribute не подавляет члены из класса в та же сборка.
Если вы действительно хотите решить этот аспект, следующий класс может оказаться полезным и также проясняет намерение .
public sealed class TriggerField<T>
{
private T data;
///<summary>raised *after* the value changes, (old, new)</summary>
public event Action<T,T> OnSet;
public TriggerField() { }
///<summary>the initial value does NOT trigger the onSet</summary>
public TriggerField(T initial) { this.data=initial; }
public TriggerField(Action<T,T> onSet) { this.OnSet += onSet; }
///<summary>the initial value does NOT trigger the onSet</summary>
public TriggerField(Action<T,T> onSet, T initial) : this(onSet)
{
this.data=initial;
}
public T Value
{
get { return this.data;}
set
{
var old = this.data;
this.data = value;
if (this.OnSet != null)
this.OnSet(old, value);
}
}
}
Позволяет (несколько подробно) использовать это примерно так:
public class Foo
{
private readonly TriggerField<string> flibble = new TriggerField<string>();
private int versionCount = 0;
public Foo()
{
flibble.OnSet += (old,current) => this.versionCount++;
}
public string Flibble
{
get { return this.flibble.Value; }
set { this.flibble.Value = value; }
}
}
в качестве альтернативы вы можете выбрать менее подробный вариант, но доступ к Flibble осуществляется не идиоматическим bar.Flibble.Value = "x";
, что было бы проблематично в сценариях рефлексии
public class Bar
{
public readonly TriggerField<string> Flibble;
private int versionCount = 0;
public Bar()
{
Flibble = new TriggerField<string>((old,current) => this.versionCount++);
}
}
Для автоматического изменения основных режимов вы можете добавить в свой файл .emacs следующее:
(add-to-list 'auto-mode-alist '("^\\*erl-output\\*$" . my-major-mode))
Это не сработает для вас; это для выбора режима основного , и вам нужен выбор режима второстепенный .
Вместо этого вы можете попробовать Hook . В руководстве говорится:
Хук - это переменная Лиспа, которая содержит список функций, которые должны быть вызваны в каком-то четко определенном случае.
Таким образом, вы должны иметь возможность написать функцию, которая устанавливает второстепенный режим, когда это необходимо. Глядя на Список стандартных хуков , я думаю, вам стоит попробовать temp-buffer-setup-hook
или temp-buffer-show-hook
.
Вы'
Обернуть его в класс? В любом случае, свойство свойства немного похоже на это, связывая данные с методами - "Инкапсуляция", которой они бредили ...
class MyInt
{
private int n;
public static implicit operator MyInt(int v) // Set
{
MyInt tmp = new MyInt();
tmp.n = v;
return tmp;
}
public static implicit operator int(MyInt v) // Get
{
return v.n;
}
}
class MyClass
{
private MyInt myint;
public void func()
{
myint = 5;
myint.n = 2; // Can't do this.
myint = myint + 5 * 4; // Works just like an int.
}
}
Я уверен, что я что-то упускаю? Это кажется слишком нормальным ...
Кстати, мне очень нравится закрытие, безумно.
Я не знаю C #, но в Java у вас может быть базовый класс только с частными переменными экземпляра и общедоступными сеттерами и геттерами (должен возвращать копию экземпляра var.) и делать все остальное в унаследованном классе.
«Общим принципом проектирования» было бы «использовать наследование».
В C # нет встроенного решения, но я думаю, что ваша проблема может быть решена с помощью хорошего объектно-ориентированного дизайна: У каждого класса должна быть одна цель. Поэтому постарайтесь выделить логику вашего поля в как можно меньший класс. Это уменьшает код, из-за которого вы можете случайно получить доступ к полю. Если вы делаете такие ошибки случайно, ваш класс, вероятно, слишком велик.
Часто интерфейс хорош для ограничения доступа только к определенному «подмножеству» объекта. Если это подходит для вашего случая, конечно, зависит от ваших настроек. Более подробная информация о предстоящей работе поможет дать лучший ответ.
Нет, нет. Мне бы самому это понравилось - что-то вроде:
public string Name
{
private string name; // Only accessible within the property
get { return name; /* Extra processing here */ }
set { name = value; /* Extra processing here */ }
}
Думаю, я впервые предложил это около 5 лет назад в группах новостей C # ... Я не ожидаю, что когда-нибудь это произойдет.
Там есть различные морщины, которые следует учитывать при сериализации и т. д., но я все же думаю, что это было бы хорошо. Я бы предпочел сначала автоматически реализовать свойства только для чтения ...