Preferred style (delegates over abstract Classes or interfaces) - c#

I have a utility class library I am writing. A have written a factory class that is generic enough that with a few delegates passed in from the caller it can be reused in many different situations. However, one of my colleagues suggested that I use an abstract class or an interface so it is more explicit what functions needed to be overridden. In the model I have created to use the library you would then need to override 2 classes instead of just one. What criteria determines when it is appropriate to use delegate functions or interfaces.
Using a delegate pattern.
Class A
{
Func<string , ReultClass> fun1 {get;set;}
FactoryObj CreateObj()
{
return fun1("")
}
}
Using an interface pattern
Class B
{
InterfaceObj{get;set;}
FactoryObj CreateObj()
{
return InterfaceObj.fun1("")
}
}

If the design is such that the class depends on another class (even a simple class), I would recommend the interface approach, since the object does have to depend on outside code:
interface IA
{
ResultClass Fun1(string arg);
}
In this case, you can still use delegates; I usually write my "anonymous" classes (as Microsoft calls them) with explicit interface implementations, so the name of the delegate property is the same as the name of the interface method it implements:
class AnonymousA : IA
{
Func<string, ResultClass> Fun1 { get; set; }
ResultClass IA.Fun1(string arg) { return this.Fun1(arg); }
}
If there are generics involved (e.g., IA<ResultClass> and the corresponding AnonymousA<ResultClass>), then it's useful to define a factory class, just to clean up the creation syntax:
static class Anonymous
{
public static IA<ResultClass> A<ResultClass>(Func<string, ResultClass> fun1)
{ return new AnonymousA<ResultClass> { Fun1 = fun1 }
}

I would think you would want to change the signature of the method. Instead of making the delegate a property on your class, make that a parameter you need to pass in. Then, you can't even invoke your CreateObj method without passing in the required data, and the signature itself tells you what you need to pass for the method call to be successful.

does/should the factory know about the various 'concrete' versions? Are there a fixed, relatively low number of specific concrete versions? If yes for either, IMHO the abstract base is a good approach. If the caller should be able to pass in 'arbitrary' code, you could either pass in delegates, or if multiple callers may want to handle/interpret the same data, expose it as events from the base and let the various callers hook up and do their interpretation.
Unfortunately, as SLaks mentions, it kind of depends on the specific situation - it's hard to make any kind of blanket statements - even the above one is likely to be a bad idea in some situations :)

Using wrapper classes, it's possible to do anything that can be done with delegates using interfaces, and vice versa. To determine which is appropriate for a given situation, examine the common usage patterns.
For example, suppose one wants to construct at run-time a list of actions that will need to be performed when a certain object is disposed. The most common action will be to call Dispose on an object of type IDisposable, but in some cases it may be necessary to do something else (e.g. unsubscribe an event handler).
One approach would be to maintain a list of MethodInvoker delegates and invoke each in turn(*). If cleanup will require calling Dispose on an object, make a new delegate for thatObject.Dispose() and add it to the list. An alternative approach would be to keep a list of IDisposable objects, and handle other actions by creating a class called InvokeOnDispose which holds a MethodInvoker, and invokes it when Dispose is called.
The former approach would require creating a new delegate for each cleanup action, whether it simply involved calling Dispose on something, or did something else. The latter approach would not require creating any new object instances when adding an IDisposable object to the list, but adding some other action would require creating an InvokeOnDispose object in addition to a delegate.
(*) One could simply use a MulticastDelegate rather than a list of delegates, but in some circumstances (like object cleanup) an exception thrown from one cleanup operation should probably not disrupt the operation of others. While one could assemble the collection of cleanup operations using a MulticastDelegate and then use GetInvocationList to run each within a separate 'try-catch' block, it would be easier and more efficient to simply use a list of delegates from the get-go.

Related

C# Best Practice: Using a delegate or an interface as a class dependency

I have a class that requires a way to retrieve a random integer value with a maximum. I don't want this class to depend on a specific way to retrieve that random value (such as system.random). Would it be best to:
(A) Use a public delegate (or func)
public delegate int NextRandomInt(int maxValue);
public class MyClass
{
public NextRandomInt NextRandomInt { get; set; }
public MyClass(NextRandomInt nextRandomInt)
{
NextRandomInt = nextRandomInt;
}
}
(B) Use a public interface
public interface IRandomIntProvider
{
int NextInt(int maxValue);
}
public class MyClass
{
public IRandomIntProvider RandomIntProvider { get; set; }
public MyClass(IRandomIntProvider randomIntProvider)
{
RandomIntProvider = randomIntProvider;
}
}
(C) Something else all together.
Both ways work. I feel like using a delegate would be simpler and quicker to implement, but the interface is more readable and may be easier when dependency injection comes around.
It's slightly hair-splitting, since either an interface or a delegate will work.
One reason to prefer the delegate in this case is that you're really only depending on a method, so it's a tiny bit redundant to have to declare both the interface and the method. If your process is anything like mine, the method name was obvious but the interface name wasn't, because it doesn't really mean anything. It's a container for the method. (And I would have ended up with almost the exact same name as you did.)
Also, a delegate gives you the option to use a static method. Your class still depends on an abstraction, so you can pass in a mocked method if needed for unit testing the class. I'm not usually a big fan of static methods, but that's largely because they interfere with testability. But if you're depending on a delegate rather than directly on the function then it doesn't matter.
It depends as to how much job you want to implement using a delegate or an interface.
If your interface is going to have only one or even two methods, you could use a Func to force the same behavior. Otherwise i would use interfaces.
Mark Seemann explained just this pretty nicely here : link
To sum it up he states this:
Whenever possible, I prefer to model my APIs with delegates instead of one-method interfaces, since it gives me greater flexibility and less infrastructure code.
Obviously, this technique only works as long as you only need to abstract a single method. As soon as your abstraction needs a second method, you will need to introduce a proper interface or, preferably, an abstract base class.
To my point of view (I am sure) the second option with interface is the best. This situation is a typical example of the Strategy pattern.
Use Interface if you think that there may be another implementation of NextRandomInt() may exist in the system.
Choose delegate if you think it shall be executed as a cause of an event or callback.
Otherwise simply go with a method as class member. It's up to you if you want the method to be available as instance method or static.

What's the sense of some interfaces and of interfaces in general?

I was looking at some interface implementations as I couldn't use the 'using' keyword to be sure to dispose properly a FileInfo object in C#, but compiler gave me this error:
'System.IO.FileInfo': type used in a using statement must be implicitly convertible to 'System.IDisposable'
So, I start documenting about implementations of these particular interfaces.
I ended up seeing that all reduces to typing :IDisposable next to the class name and add a Dispose() method myself, and that's how you make an IDisposable.
First question:
What's the sense of this? Shouldn't the framework creators make those items -disposable/nullable/whatever common use interface you want- without having us to worry about it?
It's 2 years that I work as a programmer but many years that I do as a hobby and I never understood why interface are useful or what is the purpose of them. They actually seem pretty useless to me.
From what I understood their only purpose is to serve as a "contract", which is a definition I never fully understood. People like nto say contrat while they could say "It simply means that you must reimplement all the methods of the class you inherit from, even if you make them empty", instead of that awkward "contract" definition.
Anyway, why is that? Why do I need compiler to tell me that I need to implement those methods? I guess I'll never get that.
Usually I grasped concept from studying or apllying them while coding, but I swear I never found or seen for me nor my coworkers, a situation where an interface was useful, needed, a good choiche or something convenient...
I guess I'll end up never using them even if I see people do use them a lot... Why?
C#, as with many other languages, doesn't support multiple inheritance. See the Diamond Problem for example.
In any case, interfaces are C#'s way to approach multiple inheritance by avoiding some of the problems that go with it. If Class A had a method called Foo() and Class B also had a method called Foo() how could you possibly resolve which one to call when you derive from both? Interfaces by specifying what and object can do, but not how it does it.
Consider IList<T> -- the generic form of a collection that represents an expansible list. It has methods such as Add, Remove, and Clear. If someone uses your class, they shouldn't need to worry about your implementation details, only that it works. Thus, under the hood you can have a List<int> or a LinkedList<int> and it will still function the same to your clients, because you exposed only the interace -- the base contract -- for them to use.
You will use interfaces, undoubtedly. In fact, if you were writing a using statement then you were already using one.
The point of a using statement is to create an object and ensure that it is exposed at the end of the block. In order to be able to dispose the object, it must have a Dispose method. That's where the IDisposable interface comes in.
The IDisposable interface defines the Dispose method. Any class that implements IDisposable signs a contract to implement that Dispose method. The using statement requires that an object have a Dispose method in order to be able to dispose it at the end of the block and the way that it knows that that method exists is the fact that the object you're using implements IDisposable.
This sort of thing is seen all over. When you write a foreach loop, the object that you loop over must implement IEnumerable. Under the hood, the foreach loop uses the functionality defined by that interface to enumerate the specified list.
Similarly, in order to bind a WinForms control like a ComboBox, ListBox or DataGridView to a list of data, that list must implement the IList interface because the underlying data-binding mechanism uses the functionality defined by that interface.
That's basically what interfaces do: they guarantee that a specific set of functionality will be available. They make no promises about how that functionality will be implemented or what other functionality may or may not also be provided.
Think about how interfaces work elsewhere. You use a computer so you are presumably familiar in a general sense with the USB interface. In order to be USB compliant, a device must provide a specific set of functionality. How it does that and what else it does is irrelevant to the USB port on the computer though. As long as it has an appropriate USB plug that can successfully send and receive the appropriate messages then it will work.
Think of your using statement as an IDisposable port. It doesn't matter what your object does when it's Dispose method is called or what other properties and methods it has, as long as it has a method named "Dispose" that has no parameters and doesn;t return anything, it can implement IDisosable and be accepted by the using statement.
Concerning IDisposable in particular: First of all, being disposable is something very different from being nullable.
Variables of every reference type are automatically nullable, which means that you can set them to null. You do not need to implement IDisposable for that.
When you implement the IDisposable interface, you do so to free resources that the runtime cannot automatically free, or that should simply not be subject to (somewhat non-deterministic) garbage collection.For example, you might write a class whose instances open a file and write to it - when an instance of your class is not needed any more, the file should be closed. It should be closed then and there (because something else may want to access the file as of that moment), not "at some point after the class is not needed any more, at the latest when the process is terminated". Therefore, you should declare your own class to implement IDisposable (so users of your class know Dispose needs to be called, and also so they can use your class in a using block) and implement the Dispose method in a way that closes the file.
Now, as you said, interfaces in general serve as a "contract" - a guarantee for callers that your class implements a specific set of members. Thus, the simple answer to your question
Why do I need compiler to tell me that I need to implement those methods?
is "So they can be called."
Consider the following example - first, an interface, and two classes implementing it, are declared:
public interface ISomeInterface
{
bool DoSomething();
int SomeValue { get; }
}
public class Example1 : ISomeInterface
{
public bool DoSomething()
{
return true;
}
public int SomeValue {
get {
return 42;
}
}
}
public class Example2 : ISomeInterface
{
public bool DoSomething()
{
return DateTime.IsLeapYear(DateTime.Now.Year);
}
public int SomeValue {
get {
return DateTime.Now.Year;
}
}
}
Now, let's add a class with a method that returns an implementation of ISomeInterface:
public class SomeMasterClass
{
public static ISomeInterface CreateObject()
{
if (DateTime.Now.Year % 3 == 0) {
return new Example1();
} else {
return new Example2();
}
}
}
Depending on internal conditions, either an instance of Example1 or an instance of Example2 is returned. When invoking the method, you do not know which class will actually be instantiated, and you do not need to know - because both implement the interface whose members you are going to use:
ISomeInterface myObject = SomeMasterClass.CreateObject();
Console.WriteLine(myObject.DoSomething());
Console.WriteLine(myObject.SomeValue);
Without the interface, the return value of SomeMasterClass.CreateObject() would have to be typed as System.Object (because that is the most specialized common ancestor of Example1 and Example2. However, as both classes implement the ISomeInterface interface, and thus fulfil the contract imposed by that interface, you can rely on their providing of implementations for the DoSomething method and the SomeValue property.

Is there a way to hide/show certain methods when instantiating an object?

This question came to mind while I was writing a class that iterates over a list, with methods next() and previous() that will continuously loop (e.g. if at the last object, return it, and then reset index to 0)
In the constructor I was pondering adding a boolean variable, which if true would just act like a regular iterator with only next() methods and no looping. In this case, having the method previous() would make no sense. So I'm curious, is it possible to hide the previous() method in this case. Is it possible to achieve this somehow in Java or C#?.
What about other languages?
C#
It is possible by making the two methods part of two different interfaces, and casting the object to one of the two interfaces. For example:
interface ILoopingIterator
{
void Next();
void Previous();
}
interface INonLoopingIterator
{
void Next();
}
class PlaysItBothWays : ILoopingIterator, INonLoopingIterator
{
void ILoopingIterator.Next()
{
this.NextCore();
}
void ILoopingIterator.Previous()
{
// since this code will never be shared anyway, put it here
}
void INonLoopingIterator.Next()
{
this.NextCore();
}
private void NextCore()
{
// do stuff here; this method only exists so that code can be shared
}
}
Note that I have made the class implement both interfaces explicitly; this way, users of instances are forced to select which "mode" they want to use the class in. You could implement only one interface explicitly instead (providing a "default" mode that can be changed).
and now:
var looping = (ILoopingIterator) new PlaysItBothWays(); // selects mode A
var nonLooping = (INonLoopingIterator) new PlaysItBothWays(); // selects mode B
Of course this does not stop anyone from casting the instance to the "other" interface if they want to, but if the programmer wants to subvert their own code they can also use reflection which allows much more than that.
Java
In Java, the above is not possible. You can come close by having the class expose methods that return instances of one of the two interfaces, and using the returned value. Of course then the object is really a factory and not a service provider, so that's feels like cheating on the problem.
class PlaysItBothWays
{
public ILoopingIterator asLooping() { return /* something */ }
public INonLoopingIterator asNonLooping() { return /* something else */ }
}
Rather than passing a boolean to a constructor, you should simply use inheritance.
Suppose you have a base iterator that supports only next(). If that's the only functionality you need, instantiate it.
To provide more functionality, inherit from this base iterator, make a class called TwoWayIterator or something like that, and provide a previous() method.
Both of these classes will share a common super class, so you can treat them as one, and you can hide the previous() method by treating an instance as its base class.
It is not possible to hide a method like that in a statically typed language. The best you can do is implement the method to throw an exception (or equivalent) if the method is called.
There are tricks that you can do to make it appear like the methods are not there. For instance, having the class implement two interfaces, and using different factory methods to create them. However, they don't work if the constructor is used directly, or if you want the choice to be determined by the value of a constructor or factory method parameter.
Not in Java. You can't "Hide" methods at runtime. I'd suggest you to create Two interfaces
, one with the next method and the other one extending the first one and adding the "previous" method. Then, you can have 2 factories methods to create an instance of one of these classes.
Please take a look to the Java "Iterator" class
interface Iterator<T> {
T next();
}
interface LoopingIterator<T> extends Iterator<T>{
T previous();
}
Then you can cast them. Similar to the previous C# answer
You can't hide class members at run time (well, not in C# anyway - not sure about Java). If you so worried about Previous() method being used in the context where it is not doing anything useful, then simply have it throw InvalidOperationException in that case.
It is also worth noting that .NET already has standard "iterator" interface. It is called IEnumerable (and generic version IEnumerable<T>) and is forward-only.

invoking method declaration without reflection

I have a base class (order) with a set of sub classes (productorder, specialorder, partsorder etc).
Only Some of these sub classes implement a particular interface (ITrackingCustomer) which has a single method declaration (object getcustdetails()).
As part of my solution all of my orders are processed in a central place, i.e. any crud methods pass through a central layer. Within this central layer I want to do the following:
If order is of type ITrackingCustomer
Then invoke method getcustdetails()
I have this working using the following code:
if (typeof(ITrackingCustomer).IsAssignableFrom(Order.GetType()))
{
MethodInfo theMethod = Order.GetType().GetMethod("getcustdetails");
object y = theMethod.Invoke(Order, null);
}
I am happy with the first part using isassignablefrom but would like to use a less performance intensive method for the second part (i.e. the reflection using invoke).
My question is:
Is there a more efficient way of doing this as I have read that using the invoke command is costly.
ITrackingCustomer ord = Order as ITrackingCustomer;
if (ord != null)
{
object y = ord.getcustdetails();
}
You can do:
if(Order is ITrackingCustomer) {
((ITrackingCustomer)Order).getcustdetails();
}
As others have mentioned, you can use the is and as operators to determine if an object is of a certain type. However, polymorphism is usually better suited for solving this type of problem.
If it is feasible, perhaps you can place a getcustdetails() method on Order. Make it virtual if it has a suitable default implementation (i.e. return no details or null), or abstract if it makes sense that all Order types must implement it. Since you have the ITrackingCustomer interface, I suspect that an abstract method won't work well. However, for Order types that implement ITrackingCustomer, you can then implement getcustdetails() accordingly.
At this point, it sounds like you would be able to do away with ITrackingCustomer, but I can't say for certain without knowing more details about how this interface is used.
Once this is done, you won't need to perform any type checks since calling Order.getcustdetails() always dispatches to the correct concrete implementation.
If you are trying to do call by name instead of invoking a member in an interface and you want to be able to call the same method thousands of times, then other than a cast (which I assume you can't do because you don't know the type) or reflection is to JIT compile the call.
Rick Strahl has a nice blog article on the performance costs of various ways to call method and the comments lead to this article which shows how to pull a delegate out to a non-virtual method.
Finally, I wrote a blog article on how to build adapter classes on the fly. What you can do with that is make a directly callable object that meets an abstract class:
public abstract class CustomerDetailsGetter {
public abstract object getcustdetails();
}
// ...
AdapterCompiler compiler = new AdapterCompiler();
AdapterFactory<CusomterDetailsGetter> factory = compiler.DefineAdapter<CustomerDetailsGetter>(Order.GetType());
// now, my code assumes you want to construct an object from whole cloth
// but the code could be changed to invoke the default constructor and set the
// adapted object.
CustomerDetailsGetter getter = factory.Construct(null)
object info = getter.getcustdetails();
Now, I need to be clear - there are only two reasons to do this:
you want to be able to have call-by-name semantics when you know the target arguments at compile time and you don't know have the target assembly, and you want your code to be CLEAN. An example of this is code that knows it wants to create and use a particular object, but doesn't know if the assembly will be available until run time and is forbidden to have a reference.
you want to call object methods a la reflection, but want to do this fast, fast, fast and will be calling them thousands or millions of times.
If it's a "call once" thing, you're way better off writing a helper method to do what you want.

Why Doesn't C# Allow Static Methods to Implement an Interface?

Why was C# designed this way?
As I understand it, an interface only describes behaviour, and serves the purpose of describing a contractual obligation for classes implementing the interface that certain behaviour is implemented.
If classes wish to implement that behavour in a shared method, why shouldn't they?
Here is an example of what I have in mind:
// These items will be displayed in a list on the screen.
public interface IListItem {
string ScreenName();
...
}
public class Animal: IListItem {
// All animals will be called "Animal".
public static string ScreenName() {
return "Animal";
}
....
}
public class Person: IListItem {
private string name;
// All persons will be called by their individual names.
public string ScreenName() {
return name;
}
....
}
Assuming you are asking why you can't do this:
public interface IFoo {
void Bar();
}
public class Foo: IFoo {
public static void Bar() {}
}
This doesn't make sense to me, semantically. Methods specified on an interface should be there to specify the contract for interacting with an object. Static methods do not allow you to interact with an object - if you find yourself in the position where your implementation could be made static, you may need to ask yourself if that method really belongs in the interface.
To implement your example, I would give Animal a const property, which would still allow it to be accessed from a static context, and return that value in the implementation.
public class Animal: IListItem {
/* Can be tough to come up with a different, yet meaningful name!
* A different casing convention, like Java has, would help here.
*/
public const string AnimalScreenName = "Animal";
public string ScreenName(){ return AnimalScreenName; }
}
For a more complicated situation, you could always declare another static method and delegate to that. In trying come up with an example, I couldn't think of any reason you would do something non-trivial in both a static and instance context, so I'll spare you a FooBar blob, and take it as an indication that it might not be a good idea.
My (simplified) technical reason is that static methods are not in the vtable, and the call site is chosen at compile time. It's the same reason you can't have override or virtual static members. For more details, you'd need a CS grad or compiler wonk - of which I'm neither.
For the political reason, I'll quote Eric Lippert (who is a compiler wonk, and holds a Bachelor of Mathematics, Computer science and Applied Mathematics from University of Waterloo (source: LinkedIn):
...the core design principle of static methods, the principle that gives them their name...[is]...it can always be determined exactly, at compile time, what method will be called. That is, the method can be resolved solely by static analysis of the code.
Note that Lippert does leave room for a so-called type method:
That is, a method associated with a type (like a static), which does not take a non-nullable “this” argument (unlike an instance or virtual), but one where the method called would depend on the constructed type of T (unlike a static, which must be determinable at compile time).
but is yet to be convinced of its usefulness.
Most answers here seem to miss the whole point. Polymorphism can be used not only between instances, but also between types. This is often needed, when we use generics.
Suppose we have type parameter in generic method and we need to do some operation with it. We dont want to instantinate, because we are unaware of the constructors.
For example:
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
Unfortunately, I can come up only with "ugly" alternatives:
Use reflection
Ugly and beats the idea of interfaces and polymorphism.
Create completely separate factory class
This might greatly increase the complexity of the code. For example, if we are trying to model domain objects, each object would need another repository class.
Instantiate and then call the desired interface method
This can be hard to implement even if we control the source for the classes, used as generic parameters. The reason is that, for example we might need the instances to be only in well-known, "connected to DB" state.
Example:
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
in order to use instantination for solving the static interface problem we need to do the following thing:
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
This is obviously ugly and also unnecessary complicates the code for all other methods. Obviously, not an elegant solution either!
I know it's an old question, but it's interesting. The example isn't the best. I think it would be much clearer if you showed a usage case:
string DoSomething<T>() where T:ISomeFunction
{
if (T.someFunction())
...
}
Merely being able to have static methods implement an interface would not achieve what you want; what would be needed would be to have static members as part of an interface. I can certainly imagine many usage cases for that, especially when it comes to being able to create things. Two approaches I could offer which might be helpful:
Create a static generic class whose type parameter will be the type you'd be passing to DoSomething above. Each variation of this class will have one or more static members holding stuff related to that type. This information could supplied either by having each class of interest call a "register information" routine, or by using Reflection to get the information when the class variation's static constructor is run. I believe the latter approach is used by things like Comparer<T>.Default().
For each class T of interest, define a class or struct which implements IGetWhateverClassInfo<T> and satisfies a "new" constraint. The class won't actually contain any fields, but will have a static property which returns a static field with the type information. Pass the type of that class or struct to the generic routine in question, which will be able to create an instance and use it to get information about the other class. If you use a class for this purpose, you should probably define a static generic class as indicated above, to avoid having to construct a new descriptor-object instance each time. If you use a struct, instantiation cost should be nil, but every different struct type would require a different expansion of the DoSomething routine.
None of these approaches is really appealing. On the other hand, I would expect that if the mechanisms existed in CLR to provide this sort of functionality cleanly, .net would allow one to specify parameterized "new" constraints (since knowing if a class has a constructor with a particular signature would seem to be comparable in difficulty to knowing if it has a static method with a particular signature).
Short-sightedness, I'd guess.
When originally designed, interfaces were intended only to be used with instances of class
IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();
It was only with the introduction of interfaces as constraints for generics did adding a static method to an interface have a practical use.
(responding to comment:) I believe changing it now would require a change to the CLR, which would lead to incompatibilities with existing assemblies.
To the extent that interfaces represent "contracts", it seems quiet reasonable for static classes to implement interfaces.
The above arguments all seem to miss this point about contracts.
Interfaces specify behavior of an object.
Static methods do not specify a behavior of an object, but behavior that affects an object in some way.
Because the purpose of an interface is to allow polymorphism, being able to pass an instance of any number of defined classes that have all been defined to implement the defined interface... guaranteeing that within your polymorphic call, the code will be able to find the method you are calling. it makes no sense to allow a static method to implement the interface,
How would you call it??
public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
public static void MyMethod() { //Do Something; }
}
// inside of some other class ...
// How would you call the method on the interface ???
MyClass.MyMethod(); // this calls the method normally
// not through the interface...
// This next fails you can't cast a classname to a different type...
// Only instances can be Cast to a different type...
MyInterface myItf = MyClass as MyInterface;
Actually, it does.
As of Mid-2022, the current version of C# has full support for so-called static abstract members:
interface INumber<T>
{
static abstract T Zero { get; }
}
struct Fraction : INumber<Fraction>
{
public static Fraction Zero { get; } = new Fraction();
public long Numerator;
public ulong Denominator;
....
}
Please note that depending on your version of Visual Studio and your installed .NET SDK, you'll either have to update at least one of them (or maybe both), or that you'll have to enable preview features (see Use preview features & preview language in Visual Studio).
See more:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/static-virtual-interface-members
https://blog.ndepend.com/c-11-static-abstract-members/
https://khalidabuhakmeh.com/static-abstract-members-in-csharp-10-interfaces#:~:text=Static%20abstract%20members%20allow%20each,like%20any%20other%20interface%20definition.
Regarding static methods used in non-generic contexts I agree that it doesn't make much sense to allow them in interfaces, since you wouldn't be able to call them if you had a reference to the interface anyway. However there is a fundamental hole in the language design created by using interfaces NOT in a polymorphic context, but in a generic one. In this case the interface is not an interface at all but rather a constraint. Because C# has no concept of a constraint outside of an interface it is missing substantial functionality. Case in point:
T SumElements<T>(T initVal, T[] values)
{
foreach (var v in values)
{
initVal += v;
}
}
Here there is no polymorphism, the generic uses the actual type of the object and calls the += operator, but this fails since it can't say for sure that that operator exists. The simple solution is to specify it in the constraint; the simple solution is impossible because operators are static and static methods can't be in an interface and (here is the problem) constraints are represented as interfaces.
What C# needs is a real constraint type, all interfaces would also be constraints, but not all constraints would be interfaces then you could do this:
constraint CHasPlusEquals
{
static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}
T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
foreach (var v in values)
{
initVal += v;
}
}
There has been lots of talk already about making an IArithmetic for all numeric types to implement, but there is concern about efficiency, since a constraint is not a polymorphic construct, making a CArithmetic constraint would solve that problem.
Because interfaces are in inheritance structure, and static methods don't inherit well.
What you seem to want would allow for a static method to be called via both the Type or any instance of that type. This would at very least result in ambiguity which is not a desirable trait.
There would be endless debates about whether it mattered, which is best practice and whether there are performance issues doing it one way or another. By simply not supporting it C# saves us having to worry about it.
Its also likely that a compilier that conformed to this desire would lose some optimisations that may come with a more strict separation between instance and static methods.
You can think of the static methods and non-static methods of a class as being different interfaces. When called, static methods resolve to the singleton static class object, and non-static methods resolve to the instance of the class you deal with. So, if you use static and non-static methods in an interface, you'd effectively be declaring two interfaces when really we want interfaces to be used to access one cohesive thing.
To give an example where I am missing either static implementation of interface methods or what Mark Brackett introduced as the "so-called type method":
When reading from a database storage, we have a generic DataTable class that handles reading from a table of any structure. All table specific information is put in one class per table that also holds data for one row from the DB and which must implement an IDataRow interface. Included in the IDataRow is a description of the structure of the table to read from the database. The DataTable must ask for the datastructure from the IDataRow before reading from the DB. Currently this looks like:
interface IDataRow {
string GetDataSTructre(); // How to read data from the DB
void Read(IDBDataRow); // How to populate this datarow from DB data
}
public class DataTable<T> : List<T> where T : IDataRow {
public string GetDataStructure()
// Desired: Static or Type method:
// return (T.GetDataStructure());
// Required: Instantiate a new class:
return (new T().GetDataStructure());
}
}
The GetDataStructure is only required once for each table to read, the overhead for instantiating one more instance is minimal. However, it would be nice in this case here.
FYI: You could get a similar behavior to what you want by creating extension methods for the interface. The extension method would be a shared, non overridable static behavior. However, unfortunately, this static method would not be part of the contract.
Interfaces are abstract sets of defined available functionality.
Whether or not a method in that interface behaves as static or not is an implementation detail that should be hidden behind the interface. It would be wrong to define an interface method as static because you would be unnecessarily forcing the method to be implemented in a certain way.
If methods were defined as static, the class implementing the interface wouldn't be as encapsulated as it could be. Encapsulation is a good thing to strive for in object oriented design (I won't go into why, you can read that here: http://en.wikipedia.org/wiki/Object-oriented). For this reason, static methods aren't permitted in interfaces.
Static classes should be able to do this so they can be used generically. I had to instead implement a Singleton to achieve the desired results.
I had a bunch of Static Business Layer classes that implemented CRUD methods like "Create", "Read", "Update", "Delete" for each entity type like "User", "Team", ect.. Then I created a base control that had an abstract property for the Business Layer class that implemented the CRUD methods. This allowed me to automate the "Create", "Read", "Update", "Delete" operations from the base class. I had to use a Singleton because of the Static limitation.
Most people seem to forget that in OOP Classes are objects too, and so they have messages, which for some reason c# calls "static method".
The fact that differences exist between instance objects and class objects only shows flaws or shortcomings in the language.
Optimist about c# though...
OK here is an example of needing a 'type method'. I am creating one of a set of classes based on some source XML. So I have a
static public bool IsHandled(XElement xml)
function which is called in turn on each class.
The function should be static as otherwise we waste time creating inappropriate objects.
As #Ian Boyde points out it could be done in a factory class, but this just adds complexity.
It would be nice to add it to the interface to force class implementors to implement it. This would not cause significant overhead - it is only a compile/link time check and does not affect the vtable.
However, it would also be a fairly minor improvement. As the method is static, I as the caller, must call it explicitly and so get an immediate compile error if it is not implemented. Allowing it to be specified on the interface would mean this error comes marginally earlier in the development cycle, but this is trivial compared to other broken-interface issues.
So it is a minor potential feature which on balance is probably best left out.
The fact that a static class is implemented in C# by Microsoft creating a special instance of a class with the static elements is just an oddity of how static functionality is achieved. It is isn't a theoretical point.
An interface SHOULD be a descriptor of the class interface - or how it is interacted with, and that should include interactions that are static. The general definition of interface (from Meriam-Webster): the place or area at which different things meet and communicate with or affect each other. When you omit static components of a class or static classes entirely, we are ignoring large sections of how these bad boys interact.
Here is a very clear example of where being able to use interfaces with static classes would be quite useful:
public interface ICrudModel<T, Tk>
{
Boolean Create(T obj);
T Retrieve(Tk key);
Boolean Update(T obj);
Boolean Delete(T obj);
}
Currently, I write the static classes that contain these methods without any kind of checking to make sure that I haven't forgotten anything. Is like the bad old days of programming before OOP.
C# and the CLR should support static methods in interfaces as Java does. The static modifier is part of a contract definition and does have meaning, specifically that the behavior and return value do not vary base on instance although it may still vary from call to call.
That said, I recommend that when you want to use a static method in an interface and cannot, use an annotation instead. You will get the functionality you are looking for.
Static Methods within an Interface are allowed as of c# 9 (see https://www.dotnetcurry.com/csharp/simpler-code-with-csharp-9).
I think the short answer is "because it is of zero usefulness".
To call an interface method, you need an instance of the type. From instance methods you can call any static methods you want to.
I think the question is getting at the fact that C# needs another keyword, for precisely this sort of situation. You want a method whose return value depends only on the type on which it is called. You can't call it "static" if said type is unknown. But once the type becomes known, it will become static. "Unresolved static" is the idea -- it's not static yet, but once we know the receiving type, it will be. This is a perfectly good concept, which is why programmers keep asking for it. But it didn't quite fit into the way the designers thought about the language.
Since it's not available, I have taken to using non-static methods in the way shown below. Not exactly ideal, but I can't see any approach that makes more sense, at least not for me.
public interface IZeroWrapper<TNumber> {
TNumber Zero {get;}
}
public class DoubleWrapper: IZeroWrapper<double> {
public double Zero { get { return 0; } }
}
As per Object oriented concept Interface implemented by classes and
have contract to access these implemented function(or methods) using
object.
So if you want to access Interface Contract methods you have to create object. It is always must that is not allowed in case of Static methods. Static classes ,method and variables never require objects and load in memory without creating object of that area(or class) or you can say do not require Object Creation.
Conceptually there is no reason why an interface could not define a contract that includes static methods.
For the current C# language implementation, the restriction is due to the allowance of inheritance of a base class and interfaces. If "class SomeBaseClass" implements "interface ISomeInterface" and "class SomeDerivedClass : SomeBaseClass, ISomeInterface" also implements the interface, a static method to implement an interface method would fail compile because a static method cannot have same signature as an instance method (which would be present in base class to implement the interface).
A static class is functionally identical to a singleton and serves the same purpose as a singleton with cleaner syntax. Since a singleton can implement an interface, interface implementations by statics are conceptually valid.
So it simply boils down to the limitation of C# name conflict for instance and static methods of the same name across inheritance. There is no reason why C# could not be "upgraded" to support static method contracts (interfaces).
An interface is an OOPS concept, which means every member of the interface should get used through an object or instance. Hence, an interface can not have static methods.
When a class implements an interface,it is creating instance for the interface members. While a static type doesnt have an instance,there is no point in having static signatures in an interface.

Categories

Resources