{"id":4367,"date":"2014-03-30T10:08:09","date_gmt":"2014-03-30T10:08:09","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/generic-function-with-a-has-property-x-constraint-collection-of-common-programming-errors\/"},"modified":"2014-03-30T10:08:09","modified_gmt":"2014-03-30T10:08:09","slug":"generic-function-with-a-has-property-x-constraint-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/generic-function-with-a-has-property-x-constraint-collection-of-common-programming-errors\/","title":{"rendered":"generic function with a &ldquo;has property X&rdquo; constraint?-Collection of common programming errors"},"content":{"rendered":"<p>I have a third-party, closed source application that exports a COM interface, which I am using in my C#.NET application through Interop. This COM interface exports many objects that all show up as System.Object until I cast them to the appropriate interface type. I want to assign an property of all of these objects. Thus:<\/p>\n<pre><code>foreach (object x in BigComInterface.Chickens)\n{\n    (x as Chicken).attribute = value;\n}\nforeach (object x in BigComInterface.Ducks)\n{\n    (x as Duck).attribute = value;\n}\n<\/code><\/pre>\n<p>But assigning the property is likely (for application-specific reasons that are unavoidable) to throw Exceptions from which I want to recover, so I really want a try\/catch around each one. Thus:<\/p>\n<pre><code>foreach (object x in BigComInterface.Chickens)\n{\n    try\n    {\n        (x as Chicken).attribute = value;\n    }\n    catch (Exception ex)\n    {\n        \/\/ handle...\n    }\n}\nforeach (object x in BigComInterface.Ducks)\n{\n    try\n    {\n        (x as Duck).attribute = value;\n    }\n    catch (Exception ex)\n    {\n        \/\/ handle...\n    }\n}\n<\/code><\/pre>\n<p>Obviously, it would be so much cleaner to do this:<\/p>\n<pre><code>foreach (object x in BigComInterface.Chickens)\n{\n    SetAttribute(x as Chicken, value);\n}\nforeach (object x in BigComInterface.Ducks)\n{\n    SetAttribute(x as Duck, value);\n}\n\nvoid SetAttribute(T x, System.Object value)\n{\n    try\n    {\n        x.attribute = value;\n    }\n    catch\n    {\n        \/\/ handle...\n    }\n}\n<\/code><\/pre>\n<p>See the problem? My <em>x<\/em> value can be of any type, so the compiler can&#8217;t resolve <em>.attribute<\/em>. Chicken and Duck are not in any kind of inheritance tree and they do not share an interface that has <em>.attribute<\/em>. If they did, I could put a constraint for that interface on <em>T<\/em>. But since the class is closed-source, that&#8217;s not possible for me.<\/p>\n<p>What I want, in my fantasy, is something like a constraint requiring the argument to <em>have the .attribute property<\/em> regardless of whether it implements a given interface. To wit,<\/p>\n<pre><code>void SetAttribute(T x, System.Object value) where T:hasproperty(attribute)\n<\/code><\/pre>\n<p>I&#8217;m not sure what to do from here other than to cut\/paste this little try\/catch block for each of Chicken, Duck, Cow, Sheep, and so on.<\/p>\n<p>My question is: What is a good workaround for this problem of wanting to invoke a specific property on an object when the interface that implements that property cannot be known at compile time?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have a third-party, closed source application that exports a COM interface, which I am using in my C#.NET application through Interop. This COM interface exports many objects that all show up as System.Object until I cast them to the appropriate interface type. I want to assign an property of all of these objects. Thus: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4367","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=4367"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4367\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=4367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=4367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=4367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}