简体   繁体   中英

Dynamic vs Dictionary [C#]

Say I have a class called Composite which contains a collection of another class Component , all of which have a property Name . Would it be better to use a Dictionary to store the components, or would it be better to use a dynamic object.

For example, would it be better to do this:
Component component = someComposite.Components["RandomComponent"];
or this:
Component component = someComposite.Components.RandomComponent;

Where someComposite.Components is dynamic in the second example.

The second case seems to be nicer, but there's no type safety...

I want to add that at some point I will end up doing this:
DerivedComponent component = someComposite.Components["RandomComponent"] as DerivedComponent;
In which case dynamic can save me typing out the conversion.

So which is better design?

Maybe it's just me, but I see dynamic more as an convenient way to deal with COM interop and to interact with dynamic languages such as IronPython. dynamic shouldn't really be used in an all-C# program.

Use a Dictionary<string, Component> .

And have a look at System.ComponentModel (ie the IContainer and IComponent interfaces).

I want to add that at some point I will end up doing this: DerivedComponent component = someComposite.Components["RandomComponent"] as DerivedComponent; In which case dynamic can save me typing out the conversion.

In a statically-typed language, those types are there for a reason ; don't just throw them out because of a little bit of extra syntax you have to put. That syntax is there as a warning -- "Hey! I'm doing something that is not type-safe here!"

In the end, it all comes down to cost vs. benefits. You can either have the added benefit of type safety, static invocation, the IDE helping you when you refactor...or you can save yourself a tiny bit of typing (which is kind of like documentation).


Furthermore, you have to think about error conditions. With a dynamic , your code on errors will look like this if the object does not contain that definition:

try
{
    DerivedComponent c = obj.RandomComponent;
    return c;
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
    // do something here...
}
catch (InvalidCastException)
{
    // handle error
}

Compared with:

try
{
    var c = obj["RandomComponent"] as DerivedComponent;
    if (c == null)
        // deal with error...
    return c;
}
catch (KeyNotFoundException)
{
    // do something here...
}

That does not appear that you're actually saving yourself that much typing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM