Я думал, что сделаю сравнение Martijn's answer и svick's answer ...
Следующая программа возвращает следующие результаты:
Testing with exception: 2430985 ticks
Testing with reflection: 155570 ticks
void Main()
{
var random = new Random(Environment.TickCount);
dynamic test = new Test();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100000; i++)
{
TestWithException(test, FlipCoin(random));
}
sw.Stop();
Console.WriteLine("Testing with exception: " + sw.ElapsedTicks.ToString() + " ticks");
sw.Restart();
for (int i = 0; i < 100000; i++)
{
TestWithReflection(test, FlipCoin(random));
}
sw.Stop();
Console.WriteLine("Testing with reflection: " + sw.ElapsedTicks.ToString() + " ticks");
}
class Test
{
public bool Exists { get { return true; } }
}
bool FlipCoin(Random random)
{
return random.Next(2) == 0;
}
bool TestWithException(dynamic d, bool useExisting)
{
try
{
bool result = useExisting ? d.Exists : d.DoesntExist;
return true;
}
catch (Exception)
{
return false;
}
}
bool TestWithReflection(dynamic d, bool useExisting)
{
Type type = d.GetType();
return type.GetProperties().Any(p => p.Name.Equals(useExisting ? "Exists" : "DoesntExist"));
}
As a result I'd suggest using reflection.
См. Ниже
В ответ, чтобы BLAND комментарий:
Соотношения reflection:exception
тиков для 100000 итераций:
Fails 1/1: - 1:43 ticks
Fails 1/2: - 1:22 ticks
Fails 1/3: - 1:14 ticks
Fails 1/5: - 1:9 ticks
Fails 1/7: - 1:7 ticks
Fails 1/13: - 1:4 ticks
Fails 1/17: - 1:3 ticks
Fails 1/23: - 1:2 ticks
...
Fails 1/43: - 1:2 ticks
Fails 1/47: - 1:1 ticks
... достаточно справедливой - если вы ожидаете, что не в состоянии с вероятностью менее ~ 1/47, затем перейдите к исключению.
Вышеупомянутый предполагает, что вы используете GetProperties()
каждый раз. Вы можете ускорить процесс, кэшируя результат GetProperties()
для каждого типа в словаре или аналогичном. Это может помочь, если вы снова и снова проверяете один и тот же набор типов.
Там не несколько предложений здесь: http://stackoverflow.com/questions/2985161/duck-type-testing-with-c-4-for-dynamic-objects - но не принял ответ до сих пор , –
спасибо, я могу видеть, как сделать fir одним из решений, tho мне было интересно, есть ли что-нибудь, что я упускаю – roundcrisis
Возможный дубликат [Как определить, существует ли свойство в ExpandoObject?] (Http: // stackoverflow .com/questions/2839598/how-to-detect-if-a-property-exists-on-an-expandoobject) – Sebastian