Is it a bad practice to pass "this" as an argument? - c#

I'm currently tempted to write the following:
public class Class1()
{
public Class1()
{
MyProperty = new Class2(this);
}
public Class2 MyProperty { get; private set; }
}
public class Class2()
{
public Class2(Class1 class1)
{
ParentClass1 = class1;
}
public Class1 ParentClass1 { get; set; }
}
Is passing "this" as an argument a sign of a design problem? What would be a better approach?

No, there's no fundamental design problem with passing this. Obviously, this can be misused (creating coupling that's too tight by having a related class depend on values stored in your instance when values of its own would be called for, for example), but there's no general problem with it.

no it is not a problem. THats why 'this' keyword exists, to allow you to pass yourself around

It's hard to say from what you've posted. The question you should ask yourself is: why does class2 need to know about class1? What types of operations is class2 going to perform on class1 during its lifetime, and is there a better way to implement that relationship?
There are valid reasons for doing this, but it depends on the actual classes.

Generally I'd prefer to hand an interface along to the 'child' class, as this reduces coupling. If Class2 really needs access to all of Class1's services and Class2 is public in this way (not fully encapsulated and constructed by Class1), then I'd consider requiring a concrete Class1 instance in the constructor a sign of a possible design issue.

Just to ease your mind a bit:
Passing this as a parameter is even done by classes within the BCL. For example, the List<T>.Enumerator type holds a reference to its parent List<T> object in order to know if the list has been modified between enumerations (and hence when to throw an InvalidOperationException).
This is pretty standard when you've got two (or more) types that actually belong together in a tightly-knit , logically related group (such as the aforementioned collection and enumerator). I've seen plenty of cases where developers bend over backwards to avoid this kind of totally reasonable coupling for no practical reason.

No not a problem, if there is a clear need for a relationship in your design. This pattern is used often in various applications to indicate "parent" or "owner".
I've particularly used it when traversing trees in compiler implementations or in GUI toolkits.

To give an example, check out the visitor pattern:
interface IVisitor {
Visit(SomeClass c);
Visit(AnotherClass c);
}
interface IAcceptVisitor {
void Accept(IVisitor v);
}
public SomeClass : IAcceptVisitor {
void Accept(IVisitor v) {
v.Visit(this);
}
}

I do not know the memory model in C# in detail (at all). But passing this from the constructor to another object is inherently unsafe in many languages (including Java).
If you are in a constructor, the object is not constructed yet. If the other object decides to use the passed this argument at this moment, it would reference an object in an undefined state.
In your example such undefined usage does not happen, but how would you guarantee that it won't in the future? What if somebody subclasses/modifies Class2 in a manner that it uses something from ParentClass1 in its own constructor?

Related

Why do I need an explicit interface declaration here? (C#) [duplicate]

The use case is some what like this:
public class SomeClass : ICloneable
{
// Some Code
// Implementing interface method
public object Clone()
{
// Some Clonning Code
}
}
Now my question is Why is it not possible to use "SomeClass(As it is derived from object)" as a return type of Clone() method if we consider the Funda's of Covariance and Contravariance?
Can somebody explain me the reason behind this implementation of Microsoft ????
Let me rephrase the question:
Languages such as C++ allow an overriding method to have a more specific return type than the overridden method. For example, if we have types
abstract class Enclosure {}
class Aquarium : Enclosure {}
abstract class Animal
{
public virtual Enclosure GetEnclosure();
}
then this is not legal in C# but the equivalent code would be legal in C++:
class Fish : Animal
{
public override Aquarium GetEnclosure() { ...
What is this feature of C++ called?
The feature is called "return type covariance". (As another answer points out, it would also be possible to support "formal parameter type contravariance", though C++ does not.)
Why is it not supported in C#?
As I've pointed out many times, we don't have to provide a reason why a feature is not supported; the default state of all features is "not supported". It's only when huge amounts of time and effort are put into making an implementation that a feature becomes supported. Rather, features that are implemented must have reasons for them, and darn good reasons at that considering how much it costs to make them.
That said, there are two big "points against" this feature that are the primary things preventing it from getting done.
The CLR does not support it. In order to make this work we'd basically have to implement the exactly matching method and then make a helper method that calls it. It's doable but it gets to be messy.
Anders thinks it is not a very good language feature. Anders is the Chief Architect and if he thinks it is a bad feature, odds are good its not going to get done. (Now, mind you, we thought that named and optional parameters was not worth the cost either, but that did eventually get done. Sometimes it becomes clear that you do have to grit your teeth and implement a feature that you don't really like the aesthetics of in order to satisfy a real-world demand.)
In short, there are certainly times when it would be useful, and this is a frequently requested feature. However, it's unlikely that we're going to do it. The benefit of the feature does not pay for its costs; it considerably complicates the semantic analysis of methods, and we have no really easy way to implement it.
A non-broken implementation of interface-implementation variance would have to be covariant in the return type and contravariant in the argument types.
For example:
public interface IFoo
{
object Flurp(Array array);
}
public class GoodFoo : IFoo
{
public int Flurp(Array array) { ... }
}
public class NiceFoo : IFoo
{
public object Flurp(IEnumerable enumerable) { ... }
}
Both are legal under the "new" rules, right? But what about this:
public class QuestionableFoo : IFoo
{
public double Flurp(Array array) { ... }
public object Flurp(IEnumerable enumerable) { ... }
}
Kind of hard to tell which implicit implementation is better here. The first one is an exact match for the argument type, but not the return type. The second is an exact match for the return type, but not the argument type. I'm leaning toward the first, because whoever uses the IFoo interface can only ever give it an Array, but it's still not entirely clear.
And this isn't the worst, by far. What if we do this instead:
public class EvilFoo : IFoo
{
public object Flurp(ICollection collection) { ... }
public object Flurp(ICloneable cloneable) { ... }
}
Which one wins the prize? It's a perfectly valid overload, but ICollection and ICloneable have nothing to do with each other and Array implements both of them. I can't see an obvious solution here.
It only gets worse if we start adding overloads to the interface itself:
public interface ISuck
{
Stream Munge(ArrayList list);
Stream Munge(Hashtable ht);
string Munge(NameValueCollection nvc);
object Munge(IEnumerable enumerable);
}
public class HateHateHate : ISuck
{
public FileStream Munge(ICollection collection);
public NetworkStream Munge(IEnumerable enumerable);
public MemoryStream Munge(Hashtable ht);
public Stream Munge(ICloneable cloneable);
public object Munge(object o);
public Stream Munge(IDictionary dic);
}
Good luck trying to unravel this mystery without going insane.
Of course, all of this is moot if you assert that interface implementations should only support return-type variance and not argument-type variance. But almost everyone would consider such a half-implementation to be completely broken and start spamming bug reports, so I don't think that the C# team is going to do it.
I don't know if this is the official reason why it's not supported in C# today, but it should serve as a good example of the kind of "write-only" code that it could lead to, and part of the C# team's design philosophy is to try to prevent developers from writing awful code.
You have to implement an interface's methods exactly as they are in the interface. ICloneable's Clone method returns an object, so your SomeClass must also return an object. You can, however, return a SomeClass instance in SomeClass's Clone method without any problem, but the method definition must match the interface:
public class SomeClass: IClonable
{
// Some Code
//Implementing interface method
Public object Clone()
{
SomeClass ret = new SomeClass();
// copy date from this instance to ret
return ret;
}
}
In terms of explaining the reasons behind C# decisions, Eric Lippert from Microsoft has written much explaining Contra/CoVariance in C#... here's the tag list from his blog:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
[Edit]
Specific to your question, this might be the right post.. http://blogs.msdn.com/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx
It looks like the kind of thing they could have used generics for, but it seems there is a good reason why they did not.
It is talked about here:
http://bytes.com/topic/c-sharp/answers/469671-generic-icloneable
Basically, a generic interface that would allow:
public class MyClass : IClonable<MyClass>
would also allow:
public class MyClass : IClonable<MyOtherClass>
which doesn’t really provide any benefit, and might confuse things.
According to the C# specification, you must use a method with an identical signature when overriding or implementing an interface method. Keep in mind that Microsoft does not own C#. Their C# compiler is simply their implementation of it. So why would the spec do things this way? I can only guess, but I suspect it was for ease of implementation.

Readonly field vs abstract getter-only property

What are the advantages and disadvantages of having a readonly field compared to having inheritors implement an abstract getter-only property (using C# as an example here, but I guess that doesn't really matter much).
Here are both ways to do this:
readonly field; inheritors have to inject the value in the constructor
interface IFace {
public int Field { get; }
}
abstract class Base : IFace {
private readonly int field;
protected Base(int field) {
this.field = field;
}
public int Field { get { return this.field; } }
}
class Impl {
public Impl() : base(1) {
}
}
abstract getter-only property; inheriters have to implement the property
interface IFace {
public int Field { get; }
}
abstract class Base : IFace {
// default constructor can be used
public abstract int Field { get; }
}
class Impl {
public override int Field { get { return 1; } }
}
Both implementations expose a public int Field getter-only property which does not change.
However, I can see the following differences:
The value of field is bound to each instance and there's nothing preventing inheritors from allowing to receive the value in their constructors themselves (public Impl(int field) : base(field)).
Being bound to an instance, memory for the field is required for each single instance. Which might not be a big deal, but it's definitely something to keep in mind.
The conveyed intent is: the value can only be set in the constructor and cannot change later on (leaving aside reflection).
The (returned) value of Field is bound to each type, but there's nothing preventing inheritors from generating/calculating the value each time the getter is called, potentially returning a different value each time. public overried int Field { get { return DateTime.UtcNow.Second; } }
Memory is only required "in IL", since the value is (usually) not stored anywhere, but always computed before being returned (resulting in a load instruction and nothing more).
The conveyed intent should be: the value is bound to the type (and shouldn't change between calls, but there's no way to force that, right?). But rather the intent comes across as: you need to provide this property, I don't care how you implement it and which value it returns.
Are there any crucial differences I'm missing? Is one preferred over the other, or is it required to decide on a case-by-case basis?
I guess I'm looking for a construct/pattern/language feature which binds readonly (constant) values to a type, but expose the value at the instance level. I know that I can use static fields in each inheriting type, but there's no way to enforce this from a common base (or interface). Furthermore, static fields cannot be called when having only a reference to an instance of this type. Thoughts? I'm happy to receive answers in different programming languages
There is one crucial difference between pattern 1 and pattern 2 you have given.
Pattern 1 does not allow to return a different value once class is constructed because base class takes field only in constructor.
Pattern 2 allows child classes to return different values at different times. Basically - there is nothing enforced from base class if child class decides to override.
Thus - it really depends what you want to achieve and your domain logic.
Regarding the intent you are trying to achieve - in my opinion - one of the ways to tackle the implement the intention is declare a virtual method (something like getReadOnlyField() in base) rather than a read-only property. Then - child classes are free to override the virtual method - if they do not override - base implementation will still be enforced.
There cannot be any one right answer to this question. There will be multiple ways to resolve this. It all depends on your requirements.
I believe that readonly-fields and abstract-getters are two completely different concepts. The readonly-field is all about how the field should be used within the class it is defined in.
An abstract-getter is all about the interface of the class. It does not put any restrictions on how the variable is used, but it forces all class inheritors to implement the getter in order to meet the interface.
The actual question should be where to locate the public getter of the public int Field property; should it be on the base or on the inheriting class? The answer (in my option) depends on whether the base class has to know the actual value of the Field property. If so, place it on the base, otherwise just force all child classes to implement the property getter.
Your abstraction defines a contract that implementors have to comply with. That goes beyond implementing methods with the correct signatures etc. Violating it means breaking the liskov substitution principle, i.e. asking for subtle or not so subtle bugs.
I can understand if someone feels the contract must be enforced somehow, but in the end you cannot enforce complying with LSP. You can only make the intention as clear as possible by using proper documentation and usually unit tests which document behavior as well. And keep in mind that developers usually don't violate contracts or LSP on purpose. If developers have malicious intent, all bets are off anyway.
That being said, I'd say there is no actual difference in the cases you stated. Yes, the implementations are syntactically and semantically different, but other classes would only depend on IFace anyway, right? Seriously, there's no excuse to depend on concrete implementations if there already is an abstraction. So nothing stops anyone from creating a new implementation for IFace and pass that around.

C# class design - what can I use instead of "static abstract"?

I want to do the following
public abstract class MyAbstractClass
{
public static abstract int MagicId
{
get;
}
public static void DoSomeMagic()
{
// Need to get the MagicId value defined in the concrete implementation
}
}
public class MyConcreteClass : MyAbstractClass
{
public static override int MagicId
{
get { return 123; }
}
}
However I can't because you can't have static abstract members.
I understand why I can't do this - any recommendations for a design that will achieve much the same result?
(For clarity - I am trying to provide a library with an abstract base class but the concrete versions MUST implement a few properties/methods themselves and yes, there are good reasons for keeping it static.)
You fundamentally can't make DoSomeMagic() work with the current design. A call to MyConcreteClass.DoSomeMagic in source code will be translated into MyAbstractClasss.DoSomeMagic in the IL. The fact that it was originally called using MyConcreteClass is lost.
You might consider having a parallel class hierarchy which has the same methods but virtual - then associate each instance of the original class with an instance of the class containing the previously-static members... and there should probably only be one instance of each of those.
Would the Singleton pattern work perhaps? A link to the MSDN article describing how to implement a singleton in C#:
http://msdn.microsoft.com/en-us/library/ff650316.aspx
In your particular example, the Singelton instance could extend an abstract base class with your MagicId in it.
Just a thought :)
I would question that there are "good reasons" for making the abstract members static.
If your thinking is that these members might reflect some property of the derived class itself rather than a given instance, this does not necessarily mean the members should be static.
Consider the IList.IsFixedSize property. This is really a property of the kind of IList, not any particular instance (i.e., any T[] is going to be fixed size; it will not vary from one T[] to another). But still it should be an instance member. Why? Because since multiple types may implement IList, it will vary from one IList to another.
Consider some code that takes any MyAbstractClass (from your example). If this code is designed properly, in most cases, it should not care which derived class it is actually dealing with. What matters is whatever MyAbstractClass exposes. If you make some abstract members static, basically the only way to access them would be like this:
int magicId;
if (concreteObject is MyConcreteClass) {
magicId = MyConcreteClass.MagicId;
} else if (concreteObject is MyOtherConcreteClass) {
magicId = MyOtherConcreteClass.MagicId;
}
Why such a mess? This is much better, right?
int magicId = concreteObject.MagicId;
But perhaps you have other good reasons that haven't occurred to me.
Your best option is to use an interface with MagicId only using a setter
public interface IMagic
{
int MagicId { get; }
}
By the nature of Static meaning there can only be one (yes like Highlander) you can't override them.
Using an interface assumes your client will implement the contract. If they want to have an instance for each or return the value of a Static variable it is up to them.
The good reason for keeping things static would also mean you do NOT need to have it overridden in the child class.
Not a huge fan of this option but...
You could declare the property static, not abstract, virtual and throw a NotImplementedException which returns an error message that the method has to be overridden in a derived class.
You move the error from compile time to run time though which is kinda ugly.
Languages that implement inheritance of static members do it through metaclasses (that is, classes are also objects, and these objects have a metaclass, and static inheritance exists through it). You can vaguely transpose that to the factory pattern: one class has the magic member and can create objects of the second class.
That, or use reflection. But you can't ensure at compile-time that a derived class implements statically a certain property.
Why not just make it a non-static member?
Sounds like a Monostate, perhaps? http://c2.com/cgi/wiki?MonostatePattern
The provider pattern, used by the ASP.NET membership provider, for example, might be what you're looking for.
You cannot have polymorphic behavior on static members, so you'll have a static class whose members delegate to an interface (or abstract class) field that will encapsulate the polymorphic behaviors.

Why the concept of "Covariance" and "Contravariance" are applicable while implementing the methods of an interface?

The use case is some what like this:
public class SomeClass : ICloneable
{
// Some Code
// Implementing interface method
public object Clone()
{
// Some Clonning Code
}
}
Now my question is Why is it not possible to use "SomeClass(As it is derived from object)" as a return type of Clone() method if we consider the Funda's of Covariance and Contravariance?
Can somebody explain me the reason behind this implementation of Microsoft ????
Let me rephrase the question:
Languages such as C++ allow an overriding method to have a more specific return type than the overridden method. For example, if we have types
abstract class Enclosure {}
class Aquarium : Enclosure {}
abstract class Animal
{
public virtual Enclosure GetEnclosure();
}
then this is not legal in C# but the equivalent code would be legal in C++:
class Fish : Animal
{
public override Aquarium GetEnclosure() { ...
What is this feature of C++ called?
The feature is called "return type covariance". (As another answer points out, it would also be possible to support "formal parameter type contravariance", though C++ does not.)
Why is it not supported in C#?
As I've pointed out many times, we don't have to provide a reason why a feature is not supported; the default state of all features is "not supported". It's only when huge amounts of time and effort are put into making an implementation that a feature becomes supported. Rather, features that are implemented must have reasons for them, and darn good reasons at that considering how much it costs to make them.
That said, there are two big "points against" this feature that are the primary things preventing it from getting done.
The CLR does not support it. In order to make this work we'd basically have to implement the exactly matching method and then make a helper method that calls it. It's doable but it gets to be messy.
Anders thinks it is not a very good language feature. Anders is the Chief Architect and if he thinks it is a bad feature, odds are good its not going to get done. (Now, mind you, we thought that named and optional parameters was not worth the cost either, but that did eventually get done. Sometimes it becomes clear that you do have to grit your teeth and implement a feature that you don't really like the aesthetics of in order to satisfy a real-world demand.)
In short, there are certainly times when it would be useful, and this is a frequently requested feature. However, it's unlikely that we're going to do it. The benefit of the feature does not pay for its costs; it considerably complicates the semantic analysis of methods, and we have no really easy way to implement it.
A non-broken implementation of interface-implementation variance would have to be covariant in the return type and contravariant in the argument types.
For example:
public interface IFoo
{
object Flurp(Array array);
}
public class GoodFoo : IFoo
{
public int Flurp(Array array) { ... }
}
public class NiceFoo : IFoo
{
public object Flurp(IEnumerable enumerable) { ... }
}
Both are legal under the "new" rules, right? But what about this:
public class QuestionableFoo : IFoo
{
public double Flurp(Array array) { ... }
public object Flurp(IEnumerable enumerable) { ... }
}
Kind of hard to tell which implicit implementation is better here. The first one is an exact match for the argument type, but not the return type. The second is an exact match for the return type, but not the argument type. I'm leaning toward the first, because whoever uses the IFoo interface can only ever give it an Array, but it's still not entirely clear.
And this isn't the worst, by far. What if we do this instead:
public class EvilFoo : IFoo
{
public object Flurp(ICollection collection) { ... }
public object Flurp(ICloneable cloneable) { ... }
}
Which one wins the prize? It's a perfectly valid overload, but ICollection and ICloneable have nothing to do with each other and Array implements both of them. I can't see an obvious solution here.
It only gets worse if we start adding overloads to the interface itself:
public interface ISuck
{
Stream Munge(ArrayList list);
Stream Munge(Hashtable ht);
string Munge(NameValueCollection nvc);
object Munge(IEnumerable enumerable);
}
public class HateHateHate : ISuck
{
public FileStream Munge(ICollection collection);
public NetworkStream Munge(IEnumerable enumerable);
public MemoryStream Munge(Hashtable ht);
public Stream Munge(ICloneable cloneable);
public object Munge(object o);
public Stream Munge(IDictionary dic);
}
Good luck trying to unravel this mystery without going insane.
Of course, all of this is moot if you assert that interface implementations should only support return-type variance and not argument-type variance. But almost everyone would consider such a half-implementation to be completely broken and start spamming bug reports, so I don't think that the C# team is going to do it.
I don't know if this is the official reason why it's not supported in C# today, but it should serve as a good example of the kind of "write-only" code that it could lead to, and part of the C# team's design philosophy is to try to prevent developers from writing awful code.
You have to implement an interface's methods exactly as they are in the interface. ICloneable's Clone method returns an object, so your SomeClass must also return an object. You can, however, return a SomeClass instance in SomeClass's Clone method without any problem, but the method definition must match the interface:
public class SomeClass: IClonable
{
// Some Code
//Implementing interface method
Public object Clone()
{
SomeClass ret = new SomeClass();
// copy date from this instance to ret
return ret;
}
}
In terms of explaining the reasons behind C# decisions, Eric Lippert from Microsoft has written much explaining Contra/CoVariance in C#... here's the tag list from his blog:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
[Edit]
Specific to your question, this might be the right post.. http://blogs.msdn.com/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx
It looks like the kind of thing they could have used generics for, but it seems there is a good reason why they did not.
It is talked about here:
http://bytes.com/topic/c-sharp/answers/469671-generic-icloneable
Basically, a generic interface that would allow:
public class MyClass : IClonable<MyClass>
would also allow:
public class MyClass : IClonable<MyOtherClass>
which doesn’t really provide any benefit, and might confuse things.
According to the C# specification, you must use a method with an identical signature when overriding or implementing an interface method. Keep in mind that Microsoft does not own C#. Their C# compiler is simply their implementation of it. So why would the spec do things this way? I can only guess, but I suspect it was for ease of implementation.

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