I often find it quite a distraction to have to implement an interface just because I need it once for some method call. I have to create a class somewhere else, implement the interface etc. etc.
Java has a feature called Anonymous Classes that allows one to implement the interface "inline". My question is thus: what is the nicest way you can think of of accomplishing something similar in C# using existing syntax (and I realise that "nicest" is subjective). I'm looking for nice syntax, not necessarily performance.
I implemented the following as POC in C#:
Given
interface IFoobar
{
Boolean Foobar(String s);
}
IFoobar foo = Implement.Interface<IFoobar>(new {
Foobar = new Func<String, Boolean>(s => s == "foobar")
});
This uses an anonymous object and some reflection/emit to implement the IFoobar interface (overlooking properties, generic methods and overloading). But, I'm not a fan of the new Func<...> stuff but can't do without.
Looking around I noticed a library called Impromptu Interface, but wasn't impressed by its syntax to support methods.
Is there a "nicer" way?
Edit: I'm not looking for Java vs C# flame wars.
You mentioned that you didn't need to do this often, don't care about performance, and usually want to do it during unit testing. Why not use a mocking framework?
For example, using the Moq library as an example:
public interface IFoobar {
Boolean Foobar(String s);
}
void Main() {
var foo = new Mock<IFoobar>();
foo.Setup(x => x.Foobar(It.IsAny<string>()))
.Returns((string s) => s == "foobar");
foo.Object.Foobar("notbar"); // false
foo.Object.Foobar("foobar"); // true
}
Take a look at "impromptu-interface" (https://github.com/ekonbenefits/impromptu-interface).
It will allow you to do something like...
class Program
{
static void Main(string[] args)
{
Bar b = new Bar();
b.DoSomethingWithFoo(new
{
Foobar = Return<string>.Arguments<string>(r => "foo")
}.ActLike<IFoo>());
}
}
public interface IFoo
{
string Foobar(String s);
}
public class Bar
{
public void DoSomethingWithFoo(IFoo foo)
{
Console.WriteLine(foo.Foobar("Hello World"));
}
}
A good way to do what you need in C# could be using Clay objects:
public interface IFoobar{
Func<string, bool> Foobar { get; set; }
}
With that interface you can do something like this:
dynamic New = new ClayFactory();
var foobar= New.FooBar();
foobar.Foobar = new Func<string, bool>(s => s == "foobar");
// Concrete interface implementation gets magically created!
IFoobar lou = foobar;
var result =lou.Foobar("foo");// return false
What makes the magic possible is that Clay is overriding the cast operator and creating a dynamic proxy for the interface (using Castle) that delegates the members to the Clay object.
Another way could be using the Impromptu Interface library which lets you wrap any object with an interface. That means any objects now can have dynamic behaviors. If an object has interface methods, you can directly attach behaviors to them as needed. If an object does not have interface methods, you define an interface and wrap the object in it, then, attach behaviors to the interface methods as needed.This library is an automatic way of applying the Object Adapter pattern.
If you have an interface like this:
public Interface IFoobar
{
bool Foobar(string s);
}
You can decorate an anonymous type as I show below:
//Anonymous Class
var anon = new {Foobar= Return<bool>.Arguments<string>(s => s == "foobar")};
var myInterface = anon.ActLike<IFoobar>();
Or you could use an ExpandoObject too:
dynamic expando = Build<ExpandoObject>.NewObject(Foobar: Return<bool>.Arguments<string>(s => s == "foobar"));
IMyInterface myInterface = Impromptu.ActLike(expando);
If you want to implement more than one interface, check my answer in this post.
public class Foo
{
public Func<string,bool> TheDelegate {get;set;}
}
public class Bar
{
public bool Implementation(string s)
{
return s == "True";
}
}
public class Usage
{
var myBar = new Bar();
var myFoo = new Foo { TheDelegate = myBar.Implementation };
//Or
var myFoo = new Foo { TheDelegate = x => x == "True" };
//This removes the need for Bar completely
}
As you can see in the above example, java-like hacks are completely unneeded in C#, which is a much better language.
It is possible to do a cleaner lambda syntax, however at the expense of static type checking inside Create().
I was able to use ImpromptuInterface to do this:
IFoobar foo = Implement.Interface(new {
Foobar = Function.Create(s => s == "foobar"),
});
By creating the following classes:
public static class Implement{
public static dynamic Interface(object source){
return Impromptu.ActLike(source);
}
}
public static class Function{
public static Func<dynamic> Create(Func<dynamic> del){
return del;
}
public static Func<dynamic,dynamic> Create(Func<dynamic,dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic,dynamic> del){
return del;
}
//...Add more if you want
}
Unfortunately anonymous classes in C# canĀ“t implement interfaces as in Java. However you can create some kind of adapter-class without any additional dependencies on external projects. Just create a base-class that implements your interface using a Func:
interface IFoo
{
bool DoSomething(string value);
}
class Bar : IFoo
{
private readonly Func<string, bool> m_DoSomething;
public Bar(Func<string, bool> DoSomething) { this.m_DoSomething = DoSomething; }
public bool DoSomething(string value)
{
return this.m_DoSomething(value);
}
}
Now you can call it like this:
var result = new Bar(x => true);
Or also using named arguments which is bit more obvious, in particular if your interface has more then one method:
var result = new Bar(DoSomething: x => true);
Only drawback is that you need an implementing class for every interface you have. Thus this approach is only usefull if you want to implement every interface more than once with different behaviour. So whenever I need different implementations for the same interface I use this approach.
If your biggest complaint is implementing the interface somewhere else, why not create a nested class directly before/after your method? (Compare to a Java static nested class.)
That's more idiomatic C# than creating/using some dynamic framework.
Related
Here's my class implementation where the generic is implementing two interfaces...
public class ClassA<TGeneric> : where TGeneric: IInterfaceA, IInterfaceB
I want to Mock ClassA. However, I can't use
var mock = new Mock<Class<A<IInterfaceA>>();
or
var mock = new Mock<Class<A<IInterfaceB>>();
since the generic requires implementations of both interfaces. I know you can mock objects with multiple interfaces by using the As() method on the moq, but I don't really have an object here but a generic type.
Thoughts?
Thanks...
You could define an interface that includes both interface A and B (in your test project, for testing purposes), then use that in your mock.
public interface ICanTestAAndB : IInterfaceA, IInterfaceB {}
var mock = new Mock<ClassA<ICanTestAAndB>>();
As alternative to the accepted answer you can achieve what you need by casting the mocked object to dynamic and at runtime it will work as expected.
void Main()
{
var mockA = new Mock<IIntA>();
mockA.Setup(a => a.DoA()).Returns(3);
var mockB = mockA.As<IIntB>();
mockB.Setup(iib => iib.DoB()).Returns(7);
dynamic d = mockB.Object;
TakeBoth(d);
}
void TakeBoth<T>(T obj) where T : IIntA, IIntB
{
}
public interface IIntA { int DoA(); }
public interface IIntB { int DoB(); }
I've been building a small access rules module for a project where every particular rule is reflected by a generic Rule<TEntity> object. The rule takes a delegate to execute a certain logic.
There is a RulesContext class that provides methods to check access to a certain entity "foo" like this:
rulesContext.CanIRead<Foo>(myFoo);
My intention was to store all rules build during a setup process into one collection. But every approach I tried lead to a dead end.
I thought of something like:
IDictionary<Type, Rule<object>> _rules = new Dictionary<Type, Rule<object>>();
and:
var fooRule = new Rule<Foo>(foo => foo.FullfillsACertainFooCriterion())
_rules.Add(typeof(Foo), fooRule);
The CanIRead implementation would make sure to use the dictionary properly:
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = _rules[typeof(entity)];
return rule.CanIRead(entity);
}
But the compiler does not like this: Rule<Foo> cannot be assigned to a parameter of type Rule<object>. Which kind of makes sense since it would break the contract (which says that I can use the dictionary's methods with any object as parameter which does not hold true for the fooRule which only accepts Foo typed objects. - Liskov principle)
However I cannot think of a way to solve this. How could I store Rule objects with different types in one collection?
Can you do this:
[TestFixture]
public class ContraVariance
{
[Test]
public void TestNameTest()
{
var rules = new List<IRule<object>>(); //object is used just for demo here, probably some interface of yours is better
rules.Add(new Rule<A>());
rules.Add(new Rule<B>());
}
}
public class A { }
public class B { }
public class Rule<TEntity> : IRule<TEntity>
{
}
public interface IRule<out T>
{
}
If not I think you have to have a non-generic IRule or RuleBase (class)
The out keyword int the interface means that T is out only (Covariant) you can read about it here.
I guess that out will be a problem in your case, i suspect that the rules have methods with TEntity passed as arguments.
Instead of using IDictionary<Type, object> which could hold anything (e.g. DateTime) as a value in the dictionary, you could make the values strictly Rule objects
Here
namespace RuleConsole
{
class Program
{
static void Main(string[] args)
{
var context = new RulesContext();
var objA = new A();
var objB = new B();
context.AddRule<A>(new Rule<A>(objA));
context.AddRule<B>(new Rule<B>(objB));
Console.WriteLine(context.CanIRead<A>(objA));
Console.WriteLine(context.CanIRead<B>(objB));
Console.ReadKey();
}
}
public interface IRule { }
public interface IRule<T> : IRule { }
public class Rule<T> : IRule<T>
{
T _entity;
public Rule(T entity)
{
_entity = entity;
}
}
public class A { }
public class B { }
public class RulesContext
{
Dictionary<Type, IRule> _ruleDict= new Dictionary<Type, IRule>();
public void AddRule<TEntity>(Rule<TEntity> rule)
{
_ruleDict.Add(typeof(TEntity), rule);
}
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = (IRule<TEntity>)_ruleDict[typeof(TEntity)];
//CanIRead implementation here
return rule != null;
}
}
}
That's inherently non-type-safe.
What do you want to happen if you write
_rules[typeof(Foor)].CanRead(new Bar());
You need to make a non-generic base class or interface to store in the dictionary.
Well, this is almost embarassing - but I think you've just helped me unblock my brain :-)
If the problem is that IDictionary<Type, Rule<object>> is too specific, IDictionary<Type, object> does the trick:
var fooRule = new Rule<Foo>(foo => foo.FullfillsACertainFooCriterion())
_rules.Add(typeof(Foo), fooRule);
(same as in the question, but compiles this time)
public bool CanIRead<TEntity>(TEntity entity)
{
var rule = (Rule<TEntity>)_rules[typeof(entity)];
return rule.CanIRead(entity);
}
The blocker in my brain was that I was thinking the more generic the type argument within Rule<...> was, the more objects should be allowed in the dictionary, but in this case it is the other way around: The more generic that argument is, the more specific the contract gets.
Take:
IDictionary<Rule<Foo>>
by replacing Rule by its base class object, the dictionary gets more generic. However, by replacing Foo by object, the whole thing actually gets more specialized!
The whole reason for that is that the type argument of Rule is used as an input parameter.
That's an important lesson...
When working with interfaces, I frequently run into the case where I want to ensure that a return value from a property or method, or sometimes a parameter to a method, implements TWO or more interfaces without creating a new interface.
My specific instance right now is that I want to specify that a method will result in a IEnumerable<SomeType> that also supports INotifyCollectionChanged - that way another object using the interface does not have to typecast and can still access both settings. (I don't want to use ReadOnlyObservableCollection explicitly because it only works well with ObservableCollection objects, but I would also like to leave the option open for future implementers of the interface to use it if they want to.)
I'm thinking that this can only be handled with parameters to a method, not return values, by providing a method declaration as follows:
void SetStringData<T>(T data) where T : IEnumerable<string>, INotifyCollectionChanged
Just to be clear, what I'd really like is something where the using class CAN'T specify the exact return type. Similar to the following, but obviously the syntax doesn't work or even make sense.
(IEnumerable<string>, INotifyCollectionChanged) GetStringData()
Any suggestions on how I can do this? Or, failing that, how I can achieve the same results?
The only way I can see this being done is making use of of dynamic as its all resolved at runtime, e.g.:
public dynamic GetStringData()
{
}
And:
IDisposable disposable = GetStringData();
ISomeOtherInterface other = GetStringData();
BUT you lose all type safety that the compiler would fall over on. I think the best way to do this is to make a composite interface.
public IComposite GetStringData()
{
}
And:
IEnumerable<string> enumerable = GetStringData();
No good solution, but my best guess is adding a code contract to the interface. Still requires that the caller casts the result the the interface he needs.
Something like:
Contract.Ensures(Contract.Result<object>() is IEnumerable<string>);
Contract.Ensures(Contract.Result<object>() is INotifyCollectionChanged);
You can create another abstraction (an adapter) that caches the return value and provides separate accessors for the different types that you need. This way, client code is shielded from testing and casting. You can return this adapter instead of the original return value.
Or, you can just return a tuple with your desired outputs.
Option 1: Strongly-typed out parameters (aka TryGetValue)
This allows the consumer to select the specific interface they want - even if it does return the same value.
class SettingsStore
{
public Boolean TryGetStringData( out IEnumerable<String> dataEnumerable );
public Boolean TryGetStringData( out INotifyCollectionChanged dataCollection );
}
Or:
class SettingsStore
{
public void GetStringData( out IEnumerable<String> dataEnumerable );
public void GetStringData( out INotifyCollectionChanged dataCollection );
}
(My overloads use different out parameter names to allow consumers to select overloads with explicit parameter name labels instead of type-inference which can be painful).
Option 2: Implicit type conversion
This is inspired by OneOf<T...> ( https://github.com/mcintyre321/OneOf ).
Add this type to your project:
static class ImplOf
{
public static ImplOf<TImpl,T1,T2>( TImpl implementation )
where TImpl : T1, T2
{
return new ImplOf<T1,T2>( implementation );
}
public static ImplOf<TImpl,T1,T2,T3>( TImpl implementation )
where TImpl : T1, T2, T3
{
return new ImplOf<T1,T2,T3>( implementation );
}
// etc for 4, 5, 6+ interfaces.
}
struct ImplOf<T1,T2>
{
private readonly Object impl;
public ImplOf( Object impl ) { this.impl = impl; }
public static implicit operator T1(ImplOf<T1,T2> self) => (T1)self.impl;
public static implicit operator T2(ImplOf<T1,T2> self) => (T2)self.impl;
public static implicit operator ImplOf<T1,T2>(T1 impl) => new ImplOf<T1,T2>( impl );
public static implicit operator ImplOf<T1,T2>(T2 impl) => new ImplOf<T1,T2>( impl );
// These properties are for convenience and are not required.
public T1 Interface1 => (T1)this.impl;
public T2 Interface2 => (T2)this.impl;
}
struct ImplOf<T1,T2,T3>
{
private readonly Object impl;
public ImplOf( Object impl ) { this.impl = impl; }
public static implicit operator T1(ImplOf<T1,T2,T3> self) => (T1)self.impl;
public static implicit operator T2(ImplOf<T1,T2,T3> self) => (T2)self.impl;
public static implicit operator T3(ImplOf<T1,T2,T4> self) => (T3)self.impl;
public static implicit operator ImplOf<T1,T2,T3>(T1 impl) => new ImplOf<T1,T2,T3>( impl );
public static implicit operator ImplOf<T1,T2,T3>(T2 impl) => new ImplOf<T1,T2,T3>( impl );
public static implicit operator ImplOf<T1,T2,T3>(T3 impl) => new ImplOf<T1,T2,T3>( impl );
public T1 Interface1 => (T1)this.impl;
public T2 Interface2 => (T2)this.impl;
public T3 Interface2 => (T3)this.impl;
}
// etc for 4, 5, 6+ interfaces
So your SettingsStore is now:
public class SettingsStore
{
public ImplOf<IEnumerable<String>,INotifyPropertyChanged> GetStringData()
{
MyStringDataCollection collection = ... // `MyStringDataCollection` implements both `IEnumerable<String>` and `INotifyPropertyChanged`.
return ImplOf.Create<MyStringDataCollection,IEnumerable<String>,INotifyPropertyChanged>( collection );
}
}
Because of how implicit works, consumers of GetStringData can use it like so:
IEnumerable<String> strings = store.GetStringData();
INotifyCollectionChanged collection = store.GetStringData();
// Or they can use ImplOf directly, but need to use the `InterfaceN` properties:
var collection = store.GetStringData();
foreach( String item in collection.Interface1 ) { }
Option 3: Just define a new interface
I frequently run into the case where I want to ensure that a return value from a property or method, or sometimes a parameter to a method, implements TWO or more interfaces without creating a new interface.
I don't know why you're opposed to defining a new interface type because interface inheritance is the idiomatic C# way of supporting this scenario (because C# does not yet support algebraic types like TypeScript does):
interface ISettingsStrings : IEnumerable<String>, INotifyCollectionChanged
{
// No interface body is required.
}
If you're concerned about this breaking ABI compatibility if your interface is in-the-wild and you want to add additional interfaces (e.g. IReadOnlyList<String>) then you can just do this:
interface ISettingsStrings : IEnumerable<String>, INotifyCollectionChanged
{
// No interface body is required.
}
// Declare a successor interface:
interface ISettingsStrings2 : ISettingsStrings, IReadOnlyList<String>
{
}
class SettingsStore
{
public ISettingsStrings2 GetStringData();
}
ABI consumers of the older SettingsStore.GetStringData() (which had a declared return type of ISettingsStrings) will still work because ISettingsStrings2 implements ISettingsStrings.
Perhaps a generic method would do?
T GetStringData<T>()
And add some restrictions to T
What do you know about the concrete type of the objects the method will be returning? If you know that the return from the interface will be a Widget, and that Widget supports IEnumerable and INotifyCollectionChanged, you could define the function to return Widget. If you know that the return type will be a class that you'll be designing for your indicated purpose, but you don't know exactly what class it will be, you could define a new interface INotifiableEnumerable which derives from both IEnumerable and INotifyCollectionChanged, and have any class you'll be returning implement INotifiableEnumerable. Note that in the latter case it will not be possible for your function to return classes that don't explicitly implement INotifiableEnumerable even if they happen to implement both IEnumerable and INotifyCollectionChanged.
Suppose I write a library with the following:
public class Bar { /* ... */ }
public class SomeWeirdClass<T>
where T : ???
{
public T BarMaker(Bar b)
{
// ... play with b
T t = (T)b
return (T) b;
}
}
Later, I expect users to use my library by defining their own types which are convertible to Bar and using the SomeWeirdClass 'factory'.
public class Foo
{
public static explicit operator Foo(Bar f)
{
return new Bar();
}
}
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo> weird = new SomeWeirdClass<Foo>();
Foo f = weird.BarMaker(b);
}
}
this will compile if i set where T : Foo but the problem is that I don't know about Foo at the library's compile time, and I actually want something more like where T : some class that can be instantiated, given a Bar
Is this possible? From my limited knowledge it does not seem to be, but the ingenuity of the .NET framework and its users always surprises me...
This may or not be related to the idea of static interface methods - at least, I can see the value in being able to specify the presence of factory methods to create objects (similar to the same way that you can already perform where T : new())
edit: Solution - thanks to Nick and bzIm - For other readers I'll provide a completed solution as I understand it:
edit2: This solution requires Foo to expose a public default constructor. For an even stupider better solution that does not require this see the very bottom of this post.
public class Bar {}
public class SomeWeirdClass<T>
where T : IConvertibleFromBar<T>, new()
{
public T BarMaker(Bar b)
{
T t = new T();
t.Convert(b);
return t;
}
}
public interface IConvertibleFromBar<T>
{
T Convert(Bar b);
}
public class Foo : IConvertibleFromBar<Foo>
{
public static explicit operator Foo(Bar f)
{
return null;
}
public Foo Convert(Bar b)
{
return (Foo) b;
}
}
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo> weird = new SomeWeirdClass<Foo>();
Foo f = weird.BarMaker(b);
}
}
edit2: Solution 2: Create a type convertor factory to use:
#region library defined code
public class Bar {}
public class SomeWeirdClass<T, TFactory>
where TFactory : IConvertorFactory<Bar, T>, new()
{
private static TFactory convertor = new TFactory();
public T BarMaker(Bar b)
{
return convertor.Convert(b);
}
}
public interface IConvertorFactory<TFrom, TTo>
{
TTo Convert(TFrom from);
}
#endregion
#region user defined code
public class BarToFooConvertor : IConvertorFactory<Bar, Foo>
{
public Foo Convert(Bar from)
{
return (Foo) from;
}
}
public class Foo
{
public Foo(int a) {}
public static explicit operator Foo(Bar f)
{
return null;
}
public Foo Convert(Bar b)
{
return (Foo) b;
}
}
#endregion
public class Demo
{
public static void demo()
{
Bar b = new Bar();
SomeWeirdClass<Foo, BarToFooConvertor> weird = new SomeWeirdClass<Foo, BarToFooConvertor>();
Foo f = weird.BarMaker(b);
}
}
Sounds like you found a solution to the larger problem. To answer your specific question: no, neither C# nor the CLR support the "backwards" generic type parameter constraint. That is,
class C<T> where Foo : T
"T must be Foo or a type which Foo converts to" is not supported.
There are languages that have that sort of constraint; IIRC Scala is such a language. I suspect this feature would be handy for certain uses of contravariant interfaces.
I don't think there is necessarily a syntactically cool way to do this built into the language. One possible solution to your problem could be to define a convertible interface:
public interface IConvertible<T>
where T : new() // Probably will need this
{
T Convert();
}
Then your class could be:
public class Foo : IConvertible<Bar>
{
}
I think this gets you close to where you want to be... All the Foo's and Bar's in your question sometimes make it hard to determine exactly what your intent is. Hope this helps.
Edit: Added where constraint... you will probably have to be able to create a new instance in your convertible class.
Edit 2: Made Foo inherit from ICovertible<Bar>
You could make a detour via an interface which is used as a type constraint.
For example, where T : IComparable<U> is used to constrain the type to something that can be compared to another thing, which must express this ability by implementing IComparable<another>. If you had an interface ICastableFrom<T>, you could achieve what you want by forcing them to implement ICastableFrom<Bar>.
Rather than go through the trouble of defining an interface and modifying your class to implement that interface, why not just do this?
public class SomeWeirdClass<T>
{
// aside: why is this method called 'BarMaker' if it returns a T?
public T BarMaker(Bar b, Func<Bar, T> converter)
{
// ... play with b
return converter(b);
}
}
Then in the event that you are dealing with an object of a type T to which Bar can be directly cast, this method could be called simply as follows:
var someWeirdObject = new SomeWeirdClass<Foo>();
var someBar = new Bar();
var someFoo = someWeirdObjcet.BarMaker(someBar, bar => bar as Foo);
By the way (since the Func<T, TResult> delegate emerged in .NET 3.5), you could also use Converter<TInput, TOutput> (which is exactly the same) for the converter parameter.
In C#, if you have two base interfaces with the same method (say, F()) you can use explicit implementation to perform different impl. for F(). This alloes you to differently treat the object, corresponding to the current point of view: as IMyInterface1 or IMyInterface2. Is this possible in Java?
No, there's nothing like C#'s explicit interface implementation in Java.
On the plus side, Java has covariant return types, so if you want to provide a more strongly typed implementation than the interface specifies, that's okay. For instance, this is fine:
interface Foo
{
Object getBar();
}
public class Test implements Foo
{
#Override
public String getBar()
{
return "hi";
}
}
C# wouldn't allow that (prior to C# 9, which now supports covariant return types) - and one of the ways around it is typically to implement the interface explicitly and then have a more specific public method (usually called by the interface implementation).
You can achieve similar effect using the mechanism of anonymous interface implementation in Java.
See example:
interface Foo {
void f();
}
interface Bar {
void f();
}
public class Test {
private String foo = "foo", bar = "bar";
Foo getFoo() {
return new Foo() {
#Override
public void f() {
System.out.println(foo);
}
};
}
Bar getBar() {
return new Bar() {
#Override
public void f() {
System.out.println(bar);
}
};
}
public static void main(String... args) {
Test test = new Test();
test.getFoo().f();
test.getBar().f();
}
}
You can only do this if the methods are overloaded.
If you have two method which are expected to do different things, they should have different names IMHO.
No and it should never be present in Java. It's just another bone to throw at people who can't be bothered with good design.
Explicit implementation of an interface should never be needed or used. There are better ways to solver the problem that this tries to solve.