Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile-time check a value to implement several interfaces

Let's say I want to express "a method that expect an object which implements interfaces IFoo and IBar". Something like:

void Method(IFoo+IBar param);

How can I say this using C# ?

(Is there a syntaxical construct? Or a good idiom perhaps?)


An attempt

Introduce an interface:

interface IFooBar : IFoo, IBar {}

void Method(IFooBar param);

This is bad and I regret even thinking of it :-) Looks OK at the first glance, but the sad part is that silently introduces a dependency which shouldn't be here.

The sole reason for IFooBar to exist is to be a part of Method's interface. Hence, any class of objects to be used as Method's parameter must know that this method (and that interface) exist - which wouldn't be the case otherwise. All classes implementing IFoo and IBar would need to be modified to also implement IFooBar (possibly getting to know a new assembly) - which is heavily impractical, or even impossible if we can't modify them.

Unnecessary dependency = a no-go.

A workaround

Give up static typing:

void Method(object param)
{
    if (!param is IFoo)
        throw new ArgumentException("IFoo not supported", "param");
    if (!param is IBar)
        throw new ArgumentException("IBar not supported", "param");

    // ...
}

(or: define one type in signature and dynamically check the others - preferable if one is the most important, but even more confusing)

Works correcty, but in run-time (no compile-time check). Desperately requires a doc (and everyone to read it).

Also only practical in function parameters. The code'd get massively bloated with casts if I tried to use that on a field.


A real case for this situation? For instance IList<Foo> + INotifyCollectionChanged.

like image 731
Kos Avatar asked Dec 09 '22 00:12

Kos


1 Answers

public void someMethod<T>(T param) where T : IFoo, IBar
{...}
like image 58
Servy Avatar answered Mar 09 '23 00:03

Servy