public interface IInterface1 {};
public interface IEtcetera {};
public struct CanUseThis : IEtcetera, IInterface1 {}
public class OrThat : IEtcetera, IInterface1 {}
public class Foo
{
private IInterface1 _object; // just pick one
public void setObject<T>(T obj)
where T : IInterface1, IEtcetera
{
// you now *know* that object supports all the interfaces
// you don't need the compiler to remind you
_object = obj;
}
public void ExerciseObject()
{
// completely safe due to the constraints on setObject<T>
IEtcetera itf = (IEtcetera) _object;
// ....
}
}
public class Program
{
public static void Main(string[] args)
{
var foo = new Foo();
foo.setObject(new CanUseThis());
foo.ExerciseObject();
foo.setObject(new OrThat());
foo.ExerciseObject();
}
}
cHVibGljIGludGVyZmFjZSBJSW50ZXJmYWNlMSB7fTsKcHVibGljIGludGVyZmFjZSBJRXRjZXRlcmEge307CgpwdWJsaWMgc3RydWN0IENhblVzZVRoaXMgOiBJRXRjZXRlcmEsIElJbnRlcmZhY2UxIHt9CnB1YmxpYyBjbGFzcyAgT3JUaGF0ICAgICA6IElFdGNldGVyYSwgSUludGVyZmFjZTEge30KCnB1YmxpYyBjbGFzcyBGb28KewogICAgcHJpdmF0ZSBJSW50ZXJmYWNlMSBfb2JqZWN0OyAvLyBqdXN0IHBpY2sgb25lCgogICAgcHVibGljIHZvaWQgc2V0T2JqZWN0PFQ+KFQgb2JqKQogICAgICAgIHdoZXJlIFQgOiBJSW50ZXJmYWNlMSwgSUV0Y2V0ZXJhCiAgICB7CiAgICAgICAgLy8geW91IG5vdyAqa25vdyogdGhhdCBvYmplY3Qgc3VwcG9ydHMgYWxsIHRoZSBpbnRlcmZhY2VzCiAgICAgICAgLy8geW91IGRvbid0IG5lZWQgdGhlIGNvbXBpbGVyIHRvIHJlbWluZCB5b3UKICAgICAgICBfb2JqZWN0ID0gb2JqOyAKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBFeGVyY2lzZU9iamVjdCgpCiAgICB7IAogICAgICAgIC8vIGNvbXBsZXRlbHkgc2FmZSBkdWUgdG8gdGhlIGNvbnN0cmFpbnRzIG9uIHNldE9iamVjdDxUPgogICAgICAgIElFdGNldGVyYSBpdGYgPSAoSUV0Y2V0ZXJhKSBfb2JqZWN0OwoKICAgICAgICAvLyAuLi4uCiAgICB9Cn0KCnB1YmxpYyBjbGFzcyBQcm9ncmFtCnsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBNYWluKHN0cmluZ1tdIGFyZ3MpCiAgICB7CiAgICAgICAgdmFyIGZvbyA9IG5ldyBGb28oKTsKCiAgICAgICAgZm9vLnNldE9iamVjdChuZXcgQ2FuVXNlVGhpcygpKTsKICAgICAgICBmb28uRXhlcmNpc2VPYmplY3QoKTsKCiAgICAgICAgZm9vLnNldE9iamVjdChuZXcgT3JUaGF0KCkpOwogICAgICAgIGZvby5FeGVyY2lzZU9iamVjdCgpOwogICAgfQp9Cg==