Why is static virtual impossible? Is C# dependent or just don't have any sense in the OO world?
I know the concept has already been underlined but I did not find a simple answer to the previous question.
virtual means the method called will be chosen at run-time, depending on the dynamic type of the object. static means no object is necessary to call the method.
How do you propose to do both in the same method?
Eric Lippert has a blog post about this, and as usual with his posts, he covers the subject in great depth:
https://learn.microsoft.com/en-us/archive/blogs/ericlippert/calling-static-methods-on-type-parameters-is-illegal-part-one
“virtual” and “static” are opposites! “virtual” means “determine the method to be called based on run time type information”, and “static” means “determine the method to be called solely based on compile time static analysis”
The contradiction between "static" and "virtual" is only a C# problem. If "static" were replaced by "class level", like in many other languages, no one would be blindfolded.
Too bad the choice of words made C# crippled in this respect. It is still possible to call the Type.InvokeMember method to simulate a call to a class level, virtual method. You just have to pass the method name as a string. No compile time check, no strong typing and no control that subclasses implement the method.
Some Delphi beauty:
type
TFormClass = class of TForm;
var
formClass: TFormClass;
myForm: TForm;
begin
...
formClass = GetAnyFormClassYouWouldLike;
myForm = formClass.Create(nil);
myForm.Show;
end
Guys who say that there is no sense in static virtual methods - if you don't understand how this could be possible, it does not mean that it is impossible. There are languages that allow this!! Look at Delphi, for example.
I'm going to be the one who naysays. What you are describing is not technically part of the language. Sorry. But it is possible to simulate it within the language.
Let's consider what you're asking for - you want a collection of methods that aren't attached to any particular object that can all be easily callable and replaceable at run time or compile time.
To me that sounds like what you really want is a singleton object with delegated methods.
Let's put together an example:
public interface ICurrencyWriter {
string Write(int i);
string Write(float f);
}
public class DelegatedCurrencyWriter : ICurrencyWriter {
public DelegatedCurrencyWriter()
{
IntWriter = i => i.ToString();
FloatWriter = f => f.ToString();
}
public string Write(int i) { return IntWriter(i); }
public string Write(float f) { return FloatWriter(f); }
public Func<int, string> IntWriter { get; set; }
public Func<float, string> FloatWriter { get; set; }
}
public class SingletonCurrencyWriter {
public static DelegatedCurrencyWriter Writer {
get {
if (_writer == null)
_writer = new DelegatedCurrencyWriter();
return _writer;
}
}
}
in use:
Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400.0
SingletonCurrencyWriter.Writer.FloatWriter = f => String.Format("{0} bucks and {1} little pennies.", (int)f, (int)(f * 100));
Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400 bucks and 0 little pennies
Given all this, we now have a singleton class that writes out currency values and I can change the behavior of it. I've basically defined the behavior convention at compile time and can now change the behavior at either compile time (in the constructor) or run time, which is, I believe the effect you're trying to get. If you want inheritance of behavior, you can do that to by implementing back chaining (ie, have the new method call the previous one).
That said, I don't especially recommend the example code above. For one, it isn't thread safe and there really isn't a lot in place to keep life sane. Global dependence on this kind of structure means global instability. This is one of the many ways that changeable behavior was implemented in the dim dark days of C: structs of function pointers, and in this case a single global struct.
Yes it is possible.
The most wanted use case for that is to have factories which can be "overriden"
In order to do this, you will have to rely on generic type parameters using the F-bounded polymorphism.
Example 1
Let's take a factory example:
class A: { public static A Create(int number) { return ... ;} }
class B: A { /* How to override the static Create method to return B? */}
You also want createB to be accessible and returning B objects in the B class. Or you might like A's static functions to be a library that should be extensible by B. Solution:
class A<T> where T: A<T> { public static T Create(int number) { return ...; } }
class B: A<B> { /* no create function */ }
B theb = B.Create(2); // Perfectly fine.
A thea = A.Create(0); // Here as well
Example 2 (advanced):
Let's define a static function to multiply matrices of values.
public abstract class Value<T> where T : Value<T> {
//This method is static but by subclassing T we can use virtual methods.
public static Matrix<T> MultiplyMatrix(Matrix<T> m1, Matrix<T> m2) {
return // Code to multiply two matrices using add and multiply;
}
public abstract T multiply(T other);
public abstract T add(T other);
public abstract T opposed();
public T minus(T other) {
return this.add(other.opposed());
}
}
// Abstract override
public abstract class Number<T> : Value<T> where T: Number<T> {
protected double real;
/// Note: The use of MultiplyMatrix returns a Matrix of Number here.
public Matrix<T> timesVector(List<T> vector) {
return MultiplyMatrix(new Matrix<T>() {this as T}, new Matrix<T>(vector));
}
}
public class ComplexNumber : Number<ComplexNumber> {
protected double imag;
/// Note: The use of MultiplyMatrix returns a Matrix of ComplexNumber here.
}
Now you can also use the static MultiplyMatrix method to return a matrix of complex numbers directly from ComplexNumber
Matrix<ComplexNumber> result = ComplexNumber.MultiplyMatrix(matrix1, matrix2);
While technically it's not possible to define a static virtual method, for all the reasons already pointed out here, you can functionally accomplish what I think you're trying using C# extension methods.
From Microsoft Docs:
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
Check out Extension Methods (C# Programming Guide) for more details.
In .NET, virtual method dispatch is (roughly) done by looking at the actual type of an object when the method is called at runtime, and finding the most overriding method from the class's vtable. When calling on a static class, there is no object instance to check, and so no vtable to do the lookup on.
To summarize all the options presented:
This is not a part of C# because in it, static means "not bound to anything at runtime" as it has ever since C (and maybe earlier). static entities are bound to the declaring type (thus are able to access its other static entities), but only at compile time.
This is possible in other languages where a static equivalent (if needed at all) means "bound to a type object at runtime" instead. Examples include Delphi, Python, PHP.
This can be emulated in a number of ways which can be classified as:
Use runtime binding
Static methods with a singleton object or lookalike
Virtual method that returns the same for all instances
Redefined in a derived type to return a different result (constant or derived from static members of the redefining type)
Retrieves the type object from the instance
Use compile-time binding
Use a template that modifies the code for each derived type to access the same-named entities of that type, e.g. with the CRTP
The 2022+ answer, if you are running .Net 7 or above, is that now static virtual members is now supported in interfaces. Technically it's static abstract instead of "static virtual" but the effect is that same. Standard static methods signatures can be defined in an interface and implemented statically.
Here are a few examples on the usage and syntax in .Net 7
Related
I have an abstract class called Flight and its implement a interface called IFlight and it has a virtual method, another three classes that inherit from it, the only diffrence between those three classes is the implemantation of this method. Another thing that I want to do is implement a method that accepts as an argument an object of type IFlight (could be one of those three classes) and from them i want to access the members of the abstract class (Flight). Which way there is to implement such thing ?
Flight:
class AbsFlight: IFlight
{
public int ID { get; set; }
public string Start_Point { get; set; }
public virtual float Calculate_Price(float Base_Price)
{
return Base_Price;
}
}
One of the classes (The other two looks similar except the method "Calculate_Price"):
class Charter: AbsFlight
{
public override float Calculate_Price(float Base_Price)
{
return base.Calculate_Price(Base_Price) * 3;
}
}
Main:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2)); //OK
Console.WriteLine(flight.ID); //Error
}
static void Main(string[] args)
{
List<IFlight> flights = new List<IFlight>();
flights.Add(new Regular());
flights.Add(new Charter());
flights.Add(new LowCost());
Main_SomeMethod(flights[0]);
}
Your current solution, in combination with some of the suggestions, will be a case of a mounted riding rider. You don't need an interface and a base class and testing for type.
You can solve your problem the way you're trying, with a base class and an interface. But it's overkill, and you have to kind of duplicate some stuff in the interface and the base class.
You can solve your problem with a simple base class and three derived classes where only Calculate_Price gets overridden. Put the common items in the base class. This is a very simple solution, easy to figure out, especially if C# and OOP is new to you.
You can also solve your problem with an interface and three classes, not derived. This has the disadvantage that you have to implement the interface in three classes. As Peter Csala points out, C# 8 has some language features that can help minimize this work, possibly making this just as simple as using only a base class and no interface. I am not too familiar with those features, so I can't judge whether it makes sense.
Then there is another option entirely. This touches on what zaitsman hinted at - that this is possibly an XY problem. Why do you want to distinguish between Regular, Charter and LowCost using classes derived from Flight/AbsFlight? Is it possible to just have an attribute that tells what price profile is used? Are there other fields and properties of a Flight that has nothing to do with the price, and yet also distinguishes flights? Perhaps just use one class.
About testing for class type. This is what we call code smell. Generally, if you test for class types a lot, then you defy the purpose of using classes and/or interfaces in the first place.
Your method should accept the type that has the properties it needs, in this case the AbsFlight class.
private static void Some_Method(AbsFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
Console.WriteLine(flight.ID); //OK
}
But let's says the method must accept any IFlight. In this case, it can't be sure it received an AbsFlight; it has to check. After the check you can just cast.
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
if (flight is AbsFlight)
{
Console.WriteLine(((AbsFlight)flight).ID); //OK
}
}
With c#7 there is an additional construct you can use, if you think it is clearer:
private static void Some_Method(IFlight flight)
{
Console.WriteLine(flight.Calculate_Price(2));
switch (flight)
{
case AbsFlight absFlight:
Console.WriteLine(absFlight.ID); //OK
break;
}
}
It seems to be that you are doing something wrong that this is your requirement.
When you use an interface and pass it as an argument you want it to be common to all the objects that implement it.
Anyway, if you do want to do it. You might do something like:
if (flight is Flight)
{
Flight yourFlight = (Flight)flight;
// Here you can use anything you need from Flight, e.g: yourFlight.ID
}
I am a Java programmer trying to transition to C# and I'm hoping there's a way to do something in C# that I'm accustomed to in Java: overriding a method in the declaration of an abstract object like so:
//This is the way I do it in Java and want to do in C#
Keyword k = new Keyword("quit"){
public abstract void do(String context){
//TODO Do stuff
}
};
This is for some text game stuff I've been doing for a while in Java. I've looked into abstract and virtual and anonymous classes but none of them do exactly this. Abstract and virtual want me to create a whole new subclass, but this would be time consuming and unfeasible on a large scale. Anonymous classes don't (as far as I can tell) enable me to override methods, just fields and don't provide any stabilization for me to rely on.
If there is a way to do this or something similar please explain. Thanks for your time.
That doesn't work in C#. You'll have to create a new class that inherits from Keyword.
public class MyKeyword : Keyword
{
public MyKeyword(string s) : base(s)
{ }
public override void do(string context)
{
// TODO: Do stuff.
}
}
Anonymous Types in C# aren't classes that you can provide any public methods for. They only have properties, and are intended to be a quick, intra-method way of pasing complex data from one line to the next.
To be honest, I didn't know you could do what you show in Java. That is, if I'm understanding it as kind of an in-line class derivation.
Brian Rasmussen mentions using a delegate. That would look something like this:
public delegate void DoSomething(string context);
public class Keyword
{
public DoSomething Do;
private void CallsDo()
{
if (Do != null) Do("some string");
}
}
Then you can assign to it:
Keyword k = new Keyword();
k.Do = (ctx) => { /* Do something with ctx string */ };
Delegates are probably what you are after.
You can utilize a delegate for this approach: Note the example
public class Keyword
{
public delegate void Do();
}
//Area of Execution
{
//...
Keyword k = new Keyword();
k.Do = delegate()
{
Console.Writeln("Anonymous Inner function assigned to a callback function i.e a Delegate!");
};
}
These are much like function pointers in C/C++ but that may mean nothing to you depending on your background.
A delegate is, in the simplest terms, a type-safe object that encapsulates a method/function. What this means is that it maintains a reference to the method or methods and can invoke them later through the delegate object rather than explicitly on the method(s) themselves. You can assign an anonymous function to the right hand side much the same as you can to a method in Java as you described.
hope this helps. Read more here for delegates in-depth
Delegates
I am converting some java code C# for use in my MonoDroid application. I have some snippets where interfaces are declared and then initialized in to objects. I am not 100% sure on the best approach to implement these in to C#.
For example:
public class NumberPicker {
public interface Formatter {
String toString(int value);
}
public static final NumberPicker.Formatter TWO_DIGIT_FORMATTER =
new NumberPicker.Formatter() {
//some code here
};
}
What would be the equivalent or best approach to do this in c#?
for simple "single-use" interfaces with one function (like event listeners, for example), you could think of rewriting the code to use delegates and anonymous functions instead.
delegate String Formatter(int n);
...
Formatter TWO_DIGIT_FORMATTER = delegate(int n) {
//code here
};
you can then use TWO_DIGIT_FORMATTER like a function ( TWO_DIGIT_FORMATTER(12) ).
Anonymous classes (which is what's happening in your java code) don't exist in C#, but delegates suffice in cases like this.
You would have to create a class that implements the Formatter interface and then create an instance of that.
i.e.
public class MyFormatter : IFormatter
{
public string ToString(int value)
{
//implementation
}
}
Then create an instance of MyFormatter with the new operator.
public static IFormatter TWO_DIGIT_FORMATTER = new MyFormatter ();
The 'I' prefix for interfaces is something done in the .net world but it isn't required, just convention.
So the easiest way I have found to handle this situation is to create a private nested class within your main class and then have it inherit from as many interfaces as you need. Such as IOnClickListener, IOnMouseDownListener, and then declare it at the top of your class and reuse it over and over wherever needed. Makes it much easier... If you have interfaces that repeat or have the same method names you can declare them explicitly, for example
IOnClickListener.OnClick(object sender, EventArgs)
{
}
Just as an example, you would obviously want to use the real method names and interface names. Also don't forget to dispose of the instance in your OnDestroy.
I've found a nice link on C++ Tenmplates:
http://www.cplusplus.com/doc/tutorial/templates/
and needed something similar in C#. I have a solution that seems to work but wanted opinions of others in how it relates to the above link, specifically the specialization section.
Here is a proof of concept I came up with:
public abstract class Piece
{
public object Value { get; set; }
}
public class Rook : Piece
{
public void Capture()
{
int i = (int)this.Value;
}
}
public class Pawn : Piece
{
public void CaptureEnPassant()
{
string s = (string)this.Value;
}
}
public class PieceFactory<P, T> where P : Piece, new()
{
P p;
public PieceFactory(T value)
{
p = new P();
p.Value = value;
}
public P GetPiece()
{
return p;
}
}
and then finally to call into the factory I do this:
var piece = new PieceFactory<Pawn, string>("exd6").GetPiece();
piece.CaptureEnPassant();
I've seen different solutions like using extension methods and other ways...
Just wanted to see if my way of thinking is along the lines of good patterns.
THanks so much,
David
My opinion is that your sketch is far more complex and confusing than necessary. Why does the base class have a "value" that has different meanings and different types in each derived class? Why is there a factory that takes a type parameter that must be of a particular type argument, and if it is not, then the program crashes at runtime? Get rid of all that brittle, confusing, fragile stuff. If a pawn needs a string, then make a public constructor on Pawn that takes a string, end of story. There's no need for the factory pattern at all here.
Don't be so in love with the tool that you build stuff out of it that doesn't actually make any sense. Generic types are great for things like collection classes. They're not a good fit for the chess domain.
FYI I tried converting my own template-programmed chess engine into C# for fun, and found it was slower by roughly a factor of 20 across the board [sic].
That includes stuff like parsing the gamefile format. Position lookup and move generation just had a lot of mechanical sympathy in the C++ version, that applying all the tricks could not make up for:
compiletime optimization
non-shared generics (mono specific - see here, e.g.)
unsafe code (pinned arrays, raw pointers),
unchecked blocks (as in array bounds/arithmetic overflow
value typed arrays and ref passing
short, inlinable functions
garbage prevention (custom allocation in preallocated 'realms' (just large arrays of structs preallocated)
That said, the performance benefit from using generic collections is significant, esepcially for, say List<T> where T : struct. Note however, the caveats from the link above (especially for the new constraint which has rather pathetic performance on MS. NET due to code sharing; it is basically as slow as using reflection to call the constructor, even for value types).
YMMV, but in the end I'd say
1. Go with the C# way. If you must optimize, do it the C# way
2. If all else fails, resort to P/Invoke (C++/CLR is a sweet spot if you target Windows)
I would just use generics on your base class. Does this break something in your code?
void Main()
{
var factory = new PieceFactory<Rook, int>(20);
factory.GetPiece().Dump();
}
abstract class Piece<TValue>
{
public TValue Value { get; set; }
}
class Rook : Piece<int>
{
public int Capture()
{
// Do something...
return base.Value;
}
}
class Pawn : Piece<string>
{
public string EnPassant()
{
// Do something...
return base.Value;
}
}
class PieceFactory<TKey, TValue> where TKey : Piece<TValue>, new()
{
private readonly TKey piece;
public PieceFactory(TValue value)
{
this.piece = new TKey();
this.piece.Value = value;
}
public TKey GetPiece()
{
return this.piece;
}
}
I have also put some access keywords (like this and base) and a readonly modifier in your factory.
My example below involves 2 NET classes which both contain the method CommonMethod. I would like to design MyMethod that can accept either class (Using ) while retaining the functionality common to NetClassA and NetClassB. Case1 would do just that only it is illegal as stated below. Case2 would also accomplish the goal except INetClassA and INetClassB do not exist. Therefore my question is there a way to impose a custom interface (ICommonNetMethods) on existing .NET types (Case 3)? Alternative solutions to my problem are welcomed.
// Case 1: Illegal because "where" can only have 1 base class
public void MyMethod<Ttype>(Ttype myClass) where Ttype : NetClassA, NetClassB {}
// Case 2: Legal to utlize multiple "where" interface types
public void MyMethod<Ttype>(Ttype myClass) where Ttype : INetClassA, INetClassB {}
// Case 3: For this to work ICommonNetMethods must be added to NetClassA/NetClassB
public void MyMethod<Ttype>(Ttype myClass) where Ttype : ICommonNetMethods {}
NetClassA() { This .NET class has method CommonMethod() }
NetClassB() { This .NET class has method CommonMethod() }
interface ICommonNetMethods { void CommonMethod() }
Thanks,
aidesigner
There are ways to solve this that involve creative thinking.
Most obvious:
Adapter Pattern
You build your interface, then two adapters where each take NetClassA and the other NetClassB. Your common code stays common and the specific lives in the adapters.
This works even for sealed classes. You do not dervice from NetClassA or NetClassB. I kind of want to leave this to you to figure out the implementation, come back in a day if you want the code implementation I'll post it.
Other things to look at:
Extension Methods
and/or
Reflection
More Help
=====================
= ICommonNetMethods =
=====================
| (derive)
|-------------------------------|
==================== ====================
= NetClassAAdapter = = NetClassBAdapter =
==================== ====================
| uses (not derive) | uses (not derive)
============= =============
= NetClassA = = NetClassB =
============= =============
Use Func<>:
Assume two classes, A and B, each with a function Foo (though this isn't really a requirement for this solution, observe class C, below):
public class A { int Foo() { return 1; } }
public class B { int Foo() { return 2; } }
public class C { int Deviant() { return 3; } }
Then in some code fragment, you will write:
var a = new A();
var b = new B();
var c = new C();
var fs = new Func<int>[] {() => a.Foo(), () => b.Foo(), () => c.Deviant()};
So to use this:
foreach(var func in fs)
Console.WriteLine(func());
Which in turn will output:
1
2
3
Lambda functions are a big deal in C#, and a great technology to learn. If you are unfamiliar, and would like to learn more, start at Microsoft's help page.
If you are looking at larger interfaces, consider, as has been mentioned, the adapter pattern. If the idea of wrapping each of your objects with their own concrete adapter classes seems like too much bloat for your buck, then again, Func<> to the rescue.
public interface ISomeInterface
{
void f1();
int f2(string p1);
...
}
public class FuncImplementation : ISomeInterface
{
public Action Func_f1 { get; set; }
public Func<string,int> Func_f2 { get; set; }
...
public void f1() { Func_f1(); }
public int f2(string p1) { return Func_f2(p1); }
...
}
Now you can make new Adapters inline:
var adaptA = new FuncImplementation { Func_f1 = MyF1, Func_f2 = Myf2 };
adaptA.f1();
You cannot impose an interface on existing code (unless you use a code weaver like PostSharp, but that's cheating ;-).
Instead, consider these options:
If you simply have a single method on your interface, you could use
a Delegate instead.
You could make a simple wrapper class for each of your types, and implement the interface there.
C# 4.0 introduced the dynamic keyword which allows C# developers to use duck typing (an alternative to the adapter pattern). With it, you could define MyMethod like this:
public void MyMethod(dynamic myClass)
{
myClass.CommonMethod();
}
You could then simply pass instances of NetClassA and NetClassB to MyMethod like this:
var a = new NetClassA();
var b = new NetClassB();
MyMethod(a);
MyMethod(b);
The drawback to this approach is that there's no static type checking. If NetClassA or NetClassB didn't have a method called CommonMethod that accepted no parameters, the program would compile, but fail at run time.
Also since there's no associated interface, it's not clear what functions and properties are available. Avoid using this approach in public facing assemblies.
The only way I can think of (off the top of my head) is to derive from the .NET class in question and add your interface to that implementation. I don't think that's the optimal solution, however.
Why not simply inspect the type that Ttype is in the method, and execute your code accordingly based on the type?
For example:
public void MyMethod<Ttype>(Ttype myClass)
{
string className = typeof(Ttype).Name;
switch (className)
{
case "NetClassA":
// Do stuff
break;
case "NetClassB":
// Do stuff
break;
default:
// Do something if necessary
break;
}
}
Thanks to all, I was really impressed with the various options. First I had already started pursing the delegate option ( The use of nested type parameters and recursion (C#) ) and have an almost ideal solution. The second post on this thread shows my exact implementation. This approach tries to solve the problem by passing just the needed function "Add" of NETClassA (SrgsItem) and NetClassB (SrgsElement) instead of the entire class. This is almost perfect except C# lack of "Generics Variance" support is getting in the way.
As to the other options they are all very insightful. After pursuing the delegate thread I will be trying the Adapter/Func approach proposed by Michael and Andrew (Will add comments). If you have time please follow the delegate thread above as it relates and it might help understand another facet of C#.
As of 2022, the best practice of C# is still to map external classes into Value Objects or Adaptors. To some people such as me, this is a logic overhead I wish to remove.
C# type system is closed in that we cannot extend an existing class with new interfaces. Of course, this can be mitigated by using a New-type Pattern.
class ExternalClass {
public string InfoWithDifferentLayoutOrName { get; }
}
interface IMyInterface {
string Info { get; }
}
record struct ExternalClassExtensionWrapper(ExternalClass Value): IMyInterface {
public string Info => Value.InfoWithDifferentLayoutOrName;
}
T MyAwesomeInnerFunc<T>(T input) where T: IMyInterface { ... }
But, from the view of code design, this approach does not cut down on code logic compared to a value-object mapper as you still have to write something like a wrapper. The only difference is whether you are depending on a concrete layout (VOs) or a contract (interfaces). A mysophobia do exist in the wild that insists interfaces bring lower coupling, but I don't see any lower cognitive burden in this specific case.
You will like a trait system where you can extend interfaces on others.