Все ваши звонки являются Обещаниями . Вам нужно будет дождаться успешного возврата каждого запроса, прежде чем делать следующий. Вот пример для вас
var player = new Vimeo.Player('player', { id:76979871, muted: true });
player.loadVideo(309565369).then(function(id) {
player.setCurrentTime(30).then(function(seconds) {
player.play().then(function() {
console.log('the video was played');
}).catch(function(error) {
console.log(error);
});
}).catch(function(error) {
console.log(error);
});
}).catch(function(error) {
console.log(error);
});
Я скомпилировал Ваш код, и загрузите его в ILDASM, и получил это
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: ret
} // end of method MyClass::.ctor
Отметьте ldc.i4.7
и stfld int32 dummyCSharp.MyClass::myInt
кажется, инструкции установить значения по умолчанию для myInt поля.
Таким образом, такое присвоение на самом деле компилируется как дополнительный оператор присваивания в конструкторе.
Для обнаружения такого присвоения затем Вам будет нужно отражение, чтобы размышлять над IL метода конструктора MyClass и искать stfld
(поля набора?) команды.
Править: Если я добавляю некоторое присвоение в конструктора явно:
class MyClass
{
public int myInt = 7;
public int myOtherInt;
public MyClass()
{
myOtherInt = 8;
}
}
Когда я загружаю его в ILDASM, я получил это:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 24 (0x18)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.7
IL_0002: stfld int32 dummyCSharp.MyClass::myInt
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib]System.Object::.ctor()
IL_000d: nop
IL_000e: nop
IL_000f: ldarg.0
IL_0010: ldc.i4.8
IL_0011: stfld int32 dummyCSharp.MyClass::myOtherInt
IL_0016: nop
IL_0017: ret
} // end of method MyClass::.ctor
Обратите внимание, что дополнительное присвоение на myOtherInt, который я добавил, было addded после вызова конструктор Класса объекта.
IL_0008: call instance void [mscorlib]System.Object::.ctor()
Таким образом, там у Вас есть он,
Любое присвоение, сделанное перед вызовом конструктору Класса объекта в IL, является присвоением значения по умолчанию.
Что-либо после него - оператор в фактическом коде конструктора класса.
Более обширный тест должен быть сделан все же.
p.s., который был забавой :-)
Вы могли бы хотеть рассмотреть nullable интервал для этого поведения:
class MyClass
{
int? myInt = 7;
int? myOtherInt = null;
}
Значение по умолчанию является значением как любой другой. Нет никакого способа дифференцироваться между этими двумя случаями:
int explicitly = 0;
int implicitly;
В обоих случаях Вы даете им значение 0, один путь просто сохраняет Вас ввод. Нет никакого волшебного "неинициализированного значения по умолчанию" - они - оба нуль. Они удаются, чтобы быть точно тем же. Однако то, что Вы даже рассматриваете это, указывает, что Вы серьезно от дорожки хороших идей.Что ты делаешь? Какова Ваша определенная потребность? Вы задаете неправильный вопрос ;)
Вот то, что я сделал бы, если бы я хотел создать это как общую функцию во время выполнения. Для скалярных типов я создал бы атрибут значения по умолчанию и использование это для определения defaulticity.
Вот частичное решение задачи - я уверен, что это могло быть лучше, но я просто вывел его из строя:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Linq;
using System.Data;
namespace FieldAttribute
{
[global::System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class DefaultValueAttribute : Attribute
{
public DefaultValueAttribute(int i)
{
IntVal = i;
}
public DefaultValueAttribute(bool b)
{
BoolVal = b;
}
public int IntVal { get; set; }
public bool BoolVal { get; set; }
private static FieldInfo[] GetAttributedFields(object o, string matchName)
{
Type t = o.GetType();
FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
return fields.Where(fi => ((matchName != null && fi.Name == matchName) || matchName == null) &&
(fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute)).Count() > 0).ToArray();
}
public static void SetDefaultFieldValues(object o)
{
FieldInfo[] fields = GetAttributedFields(o, null);
foreach (FieldInfo fi in fields)
{
IEnumerable<object> attrs = fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute);
foreach (Attribute attr in attrs)
{
DefaultValueAttribute def = attr as DefaultValueAttribute;
Type fieldType = fi.FieldType;
if (fieldType == typeof(Boolean))
{
fi.SetValue(o, def.BoolVal);
}
if (fieldType == typeof(Int32))
{
fi.SetValue(o, def.IntVal);
}
}
}
}
public static bool HasDefaultValue(object o, string fieldName)
{
FieldInfo[] fields = GetAttributedFields(o, null);
foreach (FieldInfo fi in fields)
{
IEnumerable<object> attrs = fi.GetCustomAttributes(false).Where(attr => attr is DefaultValueAttribute);
foreach (Attribute attr in attrs)
{
DefaultValueAttribute def = attr as DefaultValueAttribute;
Type fieldType = fi.FieldType;
if (fieldType == typeof(Boolean))
{
return (Boolean)fi.GetValue(o) == def.BoolVal;
}
if (fieldType == typeof(Int32))
{
return (Int32)fi.GetValue(o) == def.IntVal;
}
}
}
return false;
}
}
class Program
{
[DefaultValue(3)]
int foo;
[DefaultValue(true)]
bool b;
public Program()
{
DefaultValueAttribute.SetDefaultFieldValues(this);
Console.WriteLine(b + " " + foo);
Console.WriteLine("b has default value? " + DefaultValueAttribute.HasDefaultValue(this, "b"));
foo = 2;
Console.WriteLine("foo has default value? " + DefaultValueAttribute.HasDefaultValue(this, "foo"));
}
static void Main(string[] args)
{
Program p = new Program();
}
}
}
Для типов значения с помощью nullable типа для дополнительных параметров должен работать. Строки могли также быть инициализированы, чтобы опустеть, если они не являются дополнительными.
int mandatoryInt;
int? optionalInt;
Однако это действительно кажется мне немного грязный, я придерживался бы атрибутов как ясный способ сделать это.
Может быть это не простое решение...
Можно использовать атрибут de DefaultValue для устанавливания значения как:
Система импорта. ComponentModel и система. Отражение
private int myNumber = 3;
[System.ComponentModel.DefaultValue(3)]
public int MyNumber
{
get
{
return myNumber;
}
set
{
myNumber = value;
}
}
И затем восстановите значение по умолчанию с отражением:
PropertyInfo prop = this.GetType().GetProperty("MyNumber");
MessageBox.Show(((DefaultValueAttribute)(prop.GetCustomAttributes(typeof(DefaultValueAttribute), true).GetValue(0))).Value.ToString());
Что относительно того, чтобы делать универсальную структуру, которая содержит значение и инициализированный флаг?
public struct InitializationKnown<T> {
private T m_value;
private bool m_initialized;
// the default constructor leaves m_initialized = false, m_value = default(T)
// InitializationKnown() {}
InitializationKnown(T value) : m_value(value), m_initialized(true) {}
public bool initialized {
get { return m_initialized; }
}
public static operator T (InitializationKnown that) {
return that.m_value;
}
// ... other operators including assignment go here
}
Затем просто используйте это вместо участников, из которых необходимо знать об инициализации. Это - довольно основная вариация на ленивое будущее или обещание.
Этот подход использует свойство процесс get/set:
class myClass
{
#region Property: MyInt
private int _myIntDefault = 7;
private bool _myIntChanged = false;
private int _myInt;
private int MyInt
{
get
{
if (_myIntChanged)
{
return _myInt;
}
else
{
return _myIntDefault;
}
}
set
{
_myInt = value;
_myIntChanged = true;
}
}
private bool MyIntIsDefault
{
get
{
if (_myIntChanged)
{
return (_myInt == _myIntDefault);
}
else
{
return true;
}
}
}
#endregion
}
Это - много кода для одного поля - привет отрывки!
Компилятор может быть установлен генерировать предупреждение, при попытке использовать переменную прежде, чем присвоить ему значение. У меня есть настройка по умолчанию и это, как она ведет себя.
Вы могли перенести поля в частные/защищенные свойства. Если Вы хотите знать, если его набор или нет, проверьте частное поле (например, _myInt. HasValue ()).
class MyClass
{
public MyClass()
{
myInt = 7;
}
int? _myInt;
protected int myInt
{
set { _myInt = value; }
get { return _myInt ?? 0; }
}
int? _myOtherInt;
protected int myOtherInt
{
set { _myOtherInt = value; }
get { return _myOtherInt ?? 0; }
}
}
Если то, что Вы хотите, является этим, то проверьте код внизу.
Это записано в Oxygene[1], надежда, это не проблема.
[1] или Призма Delphi, как это называют теперь
var inst1 := new Sample();
var inst2 := new Sample(X := 2);
var test1 := new DefaultValueInspector<Sample>(true);
var test2 := new DefaultValueInspector<Sample>(inst2, true);
var d := test1.DefaultValueByName["X"];
var inst1HasDefault := test1.HasDefaultValue(inst1, "X");
var inst2HasDefault := test1.HasDefaultValue(inst2, "X");
Console.WriteLine("Value: {0}; inst1HasDefault: {1}; inst2HasDefault {2}",
d, inst1HasDefault, inst2HasDefault);
d := test2.DefaultValueByName["X"];
inst1HasDefault := test2.HasDefaultValue(inst1, "X");
inst2HasDefault := test2.HasDefaultValue(inst2, "X");
Console.WriteLine("Value: {0}; inst1HasDefault: {1}; inst2HasDefault {2}",
d, inst1HasDefault, inst2HasDefault);
Вывод:
Value: 1; inst1HasDefault: True; inst2HasDefault False Value: 2; inst1HasDefault: False; inst2HasDefault True
uses
System.Collections.Generic,
System.Reflection;
type
DefaultValueInspector<T> = public class
private
method get_DefaultValueByName(memberName : String): Object;
method get_DefaultValueByMember(memberInfo : MemberInfo) : Object;
protected
class method GetMemberErrorMessage(memberName : String) : String;
method GetMember(memberName : String) : MemberInfo;
property MembersByName : Dictionary<String, MemberInfo>
:= new Dictionary<String, MemberInfo>(); readonly;
property GettersByMember : Dictionary<MemberInfo, Converter<T, Object>>
:= new Dictionary<MemberInfo, Converter<T, Object>>(); readonly;
property DefaultValuesByMember : Dictionary<MemberInfo, Object>
:= new Dictionary<MemberInfo, Object>(); readonly;
public
property UseHiddenMembers : Boolean; readonly;
property DefaultValueByName[memberName : String] : Object
read get_DefaultValueByName;
property DefaultValueByMember[memberInfo : MemberInfo] : Object
read get_DefaultValueByMember;
method GetGetMethod(memberName : String) : Converter<T, Object>;
method GetGetMethod(memberInfo : MemberInfo) : Converter<T, Object>;
method HasDefaultValue(instance : T; memberName : String) : Boolean;
method HasDefaultValue(instance : T; memberInfo : MemberInfo) : Boolean;
constructor(useHiddenMembers : Boolean);
constructor(defaultInstance : T; useHiddenMembers : Boolean);
end;
implementation
constructor DefaultValueInspector<T>(useHiddenMembers : Boolean);
begin
var ctorInfo := typeOf(T).GetConstructor([]);
constructor(ctorInfo.Invoke([]) as T, useHiddenMembers);
end;
constructor DefaultValueInspector<T>(defaultInstance : T; useHiddenMembers : Boolean);
begin
var bf := iif(useHiddenMembers,
BindingFlags.NonPublic)
or BindingFlags.Public
or BindingFlags.Instance;
for mi in typeOf(T).GetMembers(bf) do
case mi.MemberType of
MemberTypes.Field :
with matching fi := FieldInfo(mi) do
begin
MembersByName.Add(fi.Name, fi);
GettersByMember.Add(mi, obj -> fi.GetValue(obj));
end;
MemberTypes.Property :
with matching pi := PropertyInfo(mi) do
if pi.GetIndexParameters().Length = 0 then
begin
MembersByName.Add(pi.Name, pi);
GettersByMember.Add(mi, obj -> pi.GetValue(obj, nil));
end;
end;
for g in GettersByMember do
with val := g.Value(DefaultInstance) do
if assigned(val) then
DefaultValuesByMember.Add(g.Key, val);
end;
class method DefaultValueInspector<T>.GetMemberErrorMessage(memberName : String) : String;
begin
exit "The member '" + memberName + "' does not exist in type " + typeOf(T).FullName
+ " or it has indexers."
end;
method DefaultValueInspector<T>.get_DefaultValueByName(memberName : String): Object;
begin
var mi := GetMember(memberName);
DefaultValuesByMember.TryGetValue(mi, out result);
end;
method DefaultValueInspector<T>.get_DefaultValueByMember(memberInfo : MemberInfo) : Object;
begin
if not DefaultValuesByMember.TryGetValue(memberInfo, out result) then
raise new ArgumentException(GetMemberErrorMessage(memberInfo.Name),
"memberName");
end;
method DefaultValueInspector<T>.GetGetMethod(memberName : String) : Converter<T, Object>;
begin
var mi := GetMember(memberName);
exit GetGetMethod(mi);
end;
method DefaultValueInspector<T>.GetGetMethod(memberInfo : MemberInfo) : Converter<T, Object>;
begin
if not GettersByMember.TryGetValue(memberInfo, out result) then
raise new ArgumentException(GetMemberErrorMessage(memberInfo.Name),
"memberName");
end;
method DefaultValueInspector<T>.GetMember(memberName : String) : MemberInfo;
begin
if not MembersByName.TryGetValue(memberName, out result) then
raise new ArgumentException(GetMemberErrorMessage(memberName),
"memberName");
end;
method DefaultValueInspector<T>.HasDefaultValue(instance : T; memberName : String) : Boolean;
begin
var getter := GetGetMethod(memberName);
var instanceValue := getter(instance);
exit Equals(DefaultValueByName[memberName], instanceValue);
end;
method DefaultValueInspector<T>.HasDefaultValue(instance : T; memberInfo : MemberInfo) : Boolean;
begin
var getter := GetGetMethod(memberInfo);
var instanceValue := getter(instance);
exit Equals(DefaultValueByMember[memberInfo], instanceValue);
end;
Делает следующую справку:
bool isAssigned = (myOtherInt == default(int));