Generic class with an interface constraint vs class implementing interface - c#

Recently I was implementing a Trie data structure and decided the Nodes could store different types of data or have its implementation varied so then I went for Node<T>. Then as I got into the algorithm for constructing the Trie I realised it required more intimate knowledge of the Node so I constrained the generic class to use an INode interface. This allows for more flexibility but felt wrong in the context of a generic class.
Generic classes have a different use case to classes which implement an interface. For example, List<T> - the algorithm can work without being dependent on a related set of abstractions. A class which implements an interface may require polymorphism/DI but the interfaces will be more specialized.
Under what circumstances do others apply a generic class T where T may implement a more specialized interface?
I thought that a generic class is used when T does not really need to expose operations/data though I can see a generic class may be used where T implements IDisposable or some other more general interface.
Any help in clarifying these points?

When faced with a choice to use a generic with an interface constraint vs. a non-generic with an interface type, I would go for generic+interface only in situations when some or all of types passed as generic arguments are value types. This would prevent my implementation from requiring costly boxing and unboxing when dealing with my structs.
For example, if the interface happens to be IComparable, I wold definitely prefer a generic with a constraint, because it would let me avoid boxing when working with primitives.
Note that an alternative way of providing functionality to your generic class is passing a delegate along with the value. For example, if you plan to do something like this
interface IScoreable {
decimal GetScore(object context);
}
class Node<T> where T : IScoreable {
...
void DoSomething(T data) {
var score = data.GetScore(someContext);
...
}
}
you can also do this:
class Node<T> {
private Func<T,object,decimal> scorer;
public Node(Func<T,object,decimal> scorer) {
this.scorer = scorer;
}
...
void DoSomething(T data) {
var score = scorer(data, someContext);
...
}
}
The second solution lets you "decouple" the scoring functionality from the type being scored, at the expense of having the caller to write a little more code.

I see nothing wrong with placing constraints on the generic argument. Having a generic argument does not imply "this will work for anything", it implies that there is more than one way that the code will make sense.
It might actually expose a completely generic concept, like List<T>, but it might expose a concept that makes sense only in some contexts (like Nullable<T> only making sense for non-nullable entities)
The constraints are just that mechanism that you use to tell the world under what circumstances the class will make sense, and will enable you to actually use that (constrained) argument in a reasonable way, i.e. calling Dispose on things that implement IDisposable
The extreme of this is when the context is very constrained, i.e. what if there are only two possible implementations? I actually have that case in my current codebase, and I use generics. I need some processing done on some data point, and currently (and in the foreseeable future) there are only two kinds of data points. This is, in principle, the code I use:
interface IDataPoint
{
SomeResultType Process();
}
class FirstKindDataPoint : IDataPoint
{
SomeResultType Process(){...}
};
class SecondKindDataPoint : IDataPoint
{
SomeResultType Process(){...}
};
class DataPointProcessor<T> where T: IDataPoint
{
void AcquireAndProcessDataPoints(){...}
}
It makes sense, even in this constrained context, because I have only one processor, so only one logic to take care of, instead of two separate processor that I will have to try to keep in sync.
This way I can have a List<T> and an Action<T> within the processor instead of a List<IDataPoint> and Action<IDataPoint> which will be incorrect in my scenario, as I need a processor for a more specific data type, that is still, implementing IDataPoint.
If I needed a processor that will process anything, as long as it is an IDataPoint, it might make sense to remove the its genericity, and simply use IDataPoint within the code.
Additionally, the point raised in #dasblinkenlight's answer is very valid. If the generic parameters can be both structs and classes than using generics will avoid any boxing.

Generics are usually used where using an interface or a base class (and this includes object) are not enough, for example where you are worried about the return value's of your function being the original type rather than just the interface, or where the parameters you are passing in may be expressions that operate on the specific type.
So if you approach the logic from the other end. The decisions on type restrictions should be the same decision as when you are choosing the types of your function parameters.

Related

C#: Is it possible to have multiple generic constraints on the same generic variable?

To illustrate it with an example:
??? public class Foo<T> where T:(ClassA || ClassB){}
Is it possible to restrict T for a number of unrelated classes in an or relationship (T is either ClassA or ClassB, but nothing else) or the only way to achieve this is to either
make ClassA and ClassB both implement the same interface
have both classes derive from the same base class
and use these as constraints?
So, to make things clear: my question does not concern whether you can have n number of generic constraints for n number of variables, I want to know if I can have n number of constraints for the very same variable.
I would implement a different type of logic for both and return the appropriate. This, of course, can be done using interfaces.
Even if you can promise that both types have the exact same members, the compiler has no way of verifying this.
By having both classes implement the same interface, you make that guarantee to the compiler that they do share at least the members of the interface, and those members are available to the generic class to use. This is the reason interfaces exist as well as the whole point of generics.
No, and if you think about it, it wouldn't be very useful.
The purpose of applying generic constraints is to ensure that the code is able to do certain operations on the type. E.g. the new() constraint ensure you can do new T(), which is not possible for an unconstrained type. But applying an "or" constraint does not provide any useful static guarantees for T, so you cant really use it for anything.
You can have multiple constraints for a single type variable though, but they are "and" constraints, i.e. they all have to be fulfilled.
If I get it right, you basically want to evaluate an expression as part of the constraint and to my best knowledge it isn't possible.
Type parameters can have multiple constraints though, just not as an expression. See here from this example:
class EmployeeList<T> where T : Employee, IEmployee, System.IComparable<T>, new()
{
// ...
}
Here T sure has multiple constraints, but not as an expression.
In this case though you might wish to take a look at your design to eliminate the need of your question.
Short answer is: No, you can't. Others already explained why, but in short you would lose the type safety that comes with generics.
If for whatever reason you still needs this, there is a solution to use method overloads and the compiler does the rest.
public void Foo<T>(T instance) where T : ClassA
{
GenericFoo(instance);
}
public void Foo<T>(T instance) where T : ClassB
{
GenericFoo(instance);
}
private void GenericFoo(object instance)
{
// Do stuff
}

Empty interfaces and abstract class enforce structure

I've been looking into empty interfaces and abstract classes and from what I have read, they are generally bad practice. I intend to use them as the foundation for a small search application that I am writing. I would write the initial search provider and others would be allowed to create their own providers as well. My code's intent is enforce relationships between the classes for anyone who would like to implement them.
Can someone chime in and describe if and why this is still a bad practice and what, if any alternatives are available.
namespace Api.SearchProviders
{
public abstract class ListingSeachResult
{
public abstract string GetResultsAsJSON();
}
public abstract class SearchParameters
{
}
public interface IListingSearchProvider
{
ListingSeachResult SearchListings(SearchParameters p);
}
}
Empty classes and interfaces are generally only "usably useful" as generic constraints; the types are not usable by themselves, and generic constraints are generally the only context in which one may use them in conjunction with something else useful. For example, if IMagicThing encapsulates some values, some implementations are mutable, and some aren't, a method which wants to record the values associated with an IMagicThing might be written something like:
void RecordValues<T>(T it) where T:IImagicThing,IIsImmutable {...}
where IIsImmutable is an empty interface whose contract says that any class which implements it and reports some value for any property must forevermore report the same value for that property. A method written as indicated could know that its parameter was contractually obligated to behave as an immutable implementation of IMagicThing.
Conceptually, if various implementations of an interface will make different promises regarding their behaviors, being able to combine those promises with constraints would seem helpful. Unfortunately, there's a rather nasty limitation with this approach: it won't be possible to pass an object to the above method unless one knows a particular type which satisfies all of the constraints, and from which object derives. If there were only one constraint, one could cast the object to that type, but that won't work if there are two or more.
Because of the above difficulty when using constrained generics, it's better to express the concept of "an IMagicThing which promises to be immutable" by defining an interface IImmutableMagicThing which derives from IMagicThing but adds no new members. A method which expects an IImmutableMagicThing won't accept any IMagicThing that doesn't implement the immutable interface, even if it happens to be immutable, but if one has a reference to an IMagicThing that happens to implement IImmutableMagicThing, one can cast that reference to the latter type and pass it to a routine that requires it.
Incidentally, there's one other usage I can see for an empty class type: as an identity token. A class need not have any members to serve as a dictionary key, a monitor lock, or the target of a weak reference. Especially if one has extension methods associated with such usage, defining an empty class for such purpose may be much more convenient than using Object.

Is it possible to constrain the constructors of classes implementing an interface?

Is it possible to set a constrain that all classes implementing an interface must have, for example, an empty constructor? Like the where T : new() constraint in generic ?
No - its not possible to place any such constraints on derived classes or implementors of a given interface.
Such constrains generally wouldn't be a particularly good idea / useful anyway, as generally when working with an interface you are normally working with instances of objects that implement that interface in which case the object has naturally already been created and such constraints are redundant. (The exception of course being generics, in which case you can use the new() constraint).
My guess is that you are attempting to create some sort of plugin system and wish to constrain implementations of your plugin interface to have some default constructor that you can use for instantiation... if this is the case then there are normally better alternatives that you can use, such as the MEF.
Can you elaborate more on why exactly you need this?
There are only four ways I can think of that you might be given a class at run-time which isn't known at compile-time. You might be given an instance of an object which implements an interface, and want to produce another one like it. That scenario would best be handled by having the interface include a NewSimilarInstance() method. You might have a method in some class which gets passed a generic type parameter which is constrained to your interface. In that scenario, the routine which accepts the generic parameter could have a new() constraint. Otherwise, you could be given a .net System.Type object or some other representation (such a string) for the type. In these latter two scenarios, no compile-time validation is going to be meaningful; doing anything with the types will require Reflection, and so you may as well use Reflection to see if they allow the creation of new instances.
No, there's nothing like that. It would be slightly odd, given that the normal use of interfaces is that the code using an interface shouldn't need to care about how it was instantiated - they shouldn't care about what the implementation class is, just that it implements the interface.
If you have some special use for this, I suggest you just write unit tests for it - if all the implementations will be in the same assembly, it should be pretty straightforward to do so, and will catch any errors at nearly the same time as compile-time...
I think you need to use a virtual class for that.
As Justin said not only you can't constrain constructor signatures using an interface but also it's not possible using an abstract class.
Maybe if you would explain why you need to place such a constrain we could find some other solutions for your problem
Inject a Factory into your generic class that can instantiate your interface, and drop the new() constraint.
Something like:
public interface IFactory<out T>
{
T CreateInstance();
}
public class GenericClass<T>
{
private readonly IFactory<T> _factory;
public GenericClass(IFactory<T> factory)
{
_factory = factory;
}
public DoSomething()
{
//...
T foo = _factory.CreateInstance();
//...
}
}

C#: Specify that a function arg must inherit from one class, and implement an interface?

I'm making a game where each Actor is represented by a GameObjectController. Game Objects that can partake in combat implement ICombatant. How can I specify that arguments to a combat function must inherit from GameObjectController and implement ICombatant? Or does this indicate that my code is structured poorly?
public void ComputeAttackUpdate(ICombatant attacker, AttackType attackType, ICombatant victim)
In the above code, I want attacker and victim to inherit from GameObjectController and implement ICombatant. Is this syntactically possible?
I'd say it probably indicates you could restructure somehow, like, have a base Combatant class that attacker and victim inherit from, which inherits from GameObjectController and implements ICombatant.
however, you could do something like
ComputeAttackUpdate<T,U>(T attacker, AttackType attackType, U victim)
where T: ICombatant, GameObjectController
where U: ICombatant, GameObjectController
Although I probably wouldn't.
Presumably all ICombatants must also be GameObjectControllers? If so, you might want to make a new interface IGameObjectController and then declare:
interface IGameObjectController
{
// Interface here.
}
interface ICombatant : IGameObjectController
{
// Interface for combat stuff here.
}
class GameObjectController : IGameObjectController
{
// Implementation here.
}
class FooActor : GameObjectController, ICombatant
{
// Implementation for fighting here.
}
It is only syntactically possible if GameObjectController itself implements ICombatant; otherwise, I would say you have a design problem.
Interfaces are intended to define the operations available on some object; base classes identify what that object is. You can only pick one or the other. If accepting the ICombatant interface as an argument is not sufficient, it might indicate that ICombatant is defined too narrowly (i.e. doesn't support everything you need it to do).
I'd have to see the specifics of what you're trying to do with this object in order to go into much more depth.
What if you did this instead:
public class GameObjectControllerCombatant : GameObjectController, ICombatant
{
// ...
}
Then derive your combatant classes from this instead of directly from GameObjectController. It still feels to me like it's breaking encapsulation, and the awkwardness of the name is a strong indication that your combatant classes are violating the Single Responsibility Principle... but it would work.
Well, sort of. You can write a generic method:
public void ComputeAttackUpdate<T>(T attacker, AttackType type, T victim)
where T : GameObjectController, ICombatant
That means T has to satisfy both the constraints you need. It's pretty grim though - and if the attacker and victim could be different (somewhat unrelated) types, you'd have to make it generic in two type parameters instead.
However, I would personally try to go for a more natural solution. This isn't a situation I find myself in, certainly. If you need to regard an argument in two different ways, perhaps you actually want two different methods?
If you control all the classes in question, and if GameObjectController doesn't define any fields, the cleanest approach would be to define an IGameObjectController (whose properties and methods match those of GameObjectController) and an ICombatantGameObjectContoller (which derives from both IGameObjectController and ICombatant). Every class which is to be usable in situations that require both interfaces must be explicitly declared as implementing ICombatantGameObjectController, even though adding that declaration wouldn't require adding any extra code. If one does that, one can use parameters, fields, and variables of type ICombatantGameObjectController without difficulty.
If you can't set up your classes and interfaces as described above, the approach offered by Jon Skeet is a generally good one, but with a nasty caveat: to call a generic function like Mr. Skeet's ComputeAttackUpdate, the compiler has to be able to determine a single type which it knows is compatible with the type of the object being passed in and with all of the constraints. If there are descendants of GameObjectController which implement ICombatant but do not derive from a common base type which also implements GameObjectController, it may be difficult to store such objects in a field and later pass them to generic routines. There is a way, and if you need to I can explain it, but it's a bit tricky.

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