I have the following class in C++/CLI and an explicit template instantiation for the int primitive..
template<typename T>
public ref class Number
{
T _value;
public:
static property T MinValue
{
T get()
{
return T::MinValue;
}
}
static property T MaxValue
{
T get()
{
return T::MaxValue;
}
}
property T Value
{
T get()
{
return _value;
}
void set(T value)
{
if( value<MinValue || value > MaxValue)
throw gcnew System::ArgumentException("Value out of range");
_value = value;
}
}
};
template ref class Number<int>;
On compiling this and inspecting the generated assembly using reflector I am able to see a class called Number<int> but while trying to instantiate this same class in C# the compiler complains about some System::Number class not taking a template argument. What am I doing wrong? Can this be done at all?
I have a work around, declare an additional class inheriting the Number<int> class. This class is now visible in C# and can be instantiated.
public ref class MyInt32 : public Number<int>
{
};
Reflector is lying a little bit here. The name of the class is not actually Number<int>. It is actually 'Number<int>'. Notice the single quotes. These are only visible when you view the type name with ildasm.
I believe this is done to make the type unbindable in most languages as they have no way of understanding how a C++ template actually works. This makes it effectively only visible to the C++ compiler which is appropriate since it's the only MS compiler that actually supports templates (templates != generics).
If your goal is to create a parametrized type in C++ CLI, and then use that type from C#, I think that you need to create a generic type rather than a template type (see Stan Lippman's Blog for the reasons why both methods exist). See here for information on how to create generic types in C++ CLI.
Related
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.
Coming from a C++ background, I'm used to sticking the const keyword into function definitions to make objects being passed in read-only values. However, I've found out that this is not possible in C# (please correct me if I'm wrong). After some Googling, I arrived at the conclusion that the only way to make a read-only object is to write an interface that only has 'get' properties and pass that in instead. Elegant, I must say.
public interface IFoo
{
IMyValInterface MyVal{ get; }
}
public class Foo : IFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
}
}
I would pass it into:
public void SomeFunction(IFoo fooVar)
{
// Cannot modify fooVar, Excellent!!
}
This is fine. However, in the rest of my code, I would like to modify my object normally. Adding a 'set' property to the interface would break my read-only restriction. I can add a 'set' property to Foo (and not IFoo), but the signature expects an interface rather than a concrete object. I would have to do some casting.
// Add this to class Foo. Might assign null if cast fails??
set { _myVal = value as ConcreteMyVal; }
// Somewhere else in the code...
IFoo myFoo = new Foo;
(myFoo as Foo).MyFoo = new ConcreteMyVal();
Is there a more elegant way of replicating const or making read-only function parameters without adding another property or a function?
I think you may be looking for a solution involving two interfaces in which one inherits from the other:
public interface IReadableFoo
{
IMyValInterface MyVal { get; }
}
public interface IWritableFoo : IReadableFoo
{
IMyValInterface MyVal { set; }
}
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public IMyValInterface MyVal
{
get { return _myVal; }
set { _myVal = value as ConcreteMyVal; }
}
}
Then you can declare methods whose parameter type “tells” whether it plans on changing the variable or not:
public void SomeFunction(IReadableFoo fooVar)
{
// Cannot modify fooVar, excellent!
}
public void SomeOtherFunction(IWritableFoo fooVar)
{
// Can modify fooVar, take care!
}
This mimics compile-time checks similar to constness in C++. As Eric Lippert correctly pointed out, this is not the same as immutability. But as a C++ programmer I think you know that.
By the way, you can achieve slightly better compile-time checking if you declare the type of the property in the class as ConcreteMyVal and implement the interface properties separately:
public class Foo : IWritableFoo
{
private ConcreteMyVal _myVal;
public ConcreteMyVal MyVal
{
get { return _myVal; }
set { _myVal = value; }
}
public IMyValInterface IReadableFoo.MyVal { get { return MyVal; } }
public IMyValInterface IWritableFoo.MyVal
{
// (or use “(ConcreteMyVal)value” if you want it to throw
set { MyVal = value as ConcreteMyVal; }
}
}
This way, the setter can only throw when accessed through the interface, but not when accessed through the class.
The closest equivalent is the in keyword. Using in makes the parameter and input parameter and prevents it from being changed inside the method. From the official C# documentation:
in - specifies that this parameter is passed by reference but is only read by the called method.
ref - specifies that this parameter is passed by reference and may be read or written by the called method.
out - specifies that this parameter is passed by reference and must be written by the called method.
First of all, you're correct: you cannot apply const or a similar keyword to parameters in C#.
However, you can use interfaces to do something along those lines. Interfaces are special in the sense, that it makes perfect sense to make an interface that only covers a specific part of a feature set. E.g. image a stack class, which implements both IPopable and IPushable. If you access the instance via the IPopable interface, you can only remove entries from the stack. If you access the instance via the IPushable interface, you can only add entries to the stack. You can use interfaces this way to get something similar to what you're asking for.
Consider Timwi's answer first. But as a second option, you could do this, making it more like the C CONST keyword.
Reference-type (object) parameters are IN parameters by default. But because they are references, their method side effects and property accesses are done to the object outside the method. The object doesn't have to be passed out. It has still been modified by the method.
However, a value-type (struct) parameter is also IN by default, and cannot have side effects or property modifications on the element that was passed in. Instead, it gets COPIED ON WRITE before going into the method. Any changes to it inside that method die when the method goes out of scope (the end of the method).
Do NOT change your classes to structs just to accommodate this need. It's a bad idea. But if they should be structs anyway, now you'll know.
BTW, half the programming community doesn't properly understand this concept but thinks they do (indeed, I've found inaccuracies on the matter of parameter direction in C# in several books). If you want to comment on the accuracy of my statements, please double check to make sure you know what you're talking about.
C#: can you make it so that a method parameter passes an object by reference but is read-only?
eg:
void MyMethod(int x, int y, read-only MyObject obj)
where obj is an object reference but this object cannot be modified during the method.
Can this be achieved in C#?
No. C# has no direct analogue to C++ const (its own const is something different). A common C# pattern for this is to pass in a interface, such as IEnumerable, that does not permit modifications. You can also create an immutable copy or wrapper.
If the class of the object you're passing was written by you, then you're in luck.
Ask yourself: if C# had a const feature, what operations on the object would I expect to be banned through a const reference to my class?
Then define an interface that leaves out the banned operations.
For example:
class MyClass
{
public string GetSomething() { ... }
public void Clobber() { ... }
public int Thing { get { ... } set { ... } }
}
The corresponding "const" interface might be:
interface IConstMyClass
{
public string GetSomething() { ... }
public int Thing { get { ... } }
}
Now amend the class:
class MyClass : IConstMyClass
{
Now you can use IConstMyClass to mean const MyClass.
void MyMethod(int x, int y, IConstMyClass obj)
Note: there will be those who will tell you that this isn't enough. What if MyMethod casts back to MyClass? But ignore them. Ultimately the implementor can use reflection to get around any aspect of the type system - see this amusing example.
The only option to stop reflection attacks is the trivial approach: make a totally disconnected clone.
This is not possible in C#.
You can prevent this by passing in an immutable object.
There is no mechanism that does this for you.
Either pass a throwaway copy, or build immutability, even if temporary, into the class itself.
why don't you make a copy of that object and do whatever you want with that copy while your obj remains not modified.
See here how to clone your object: Deep cloning objects
What tools/libraries exist that will take a struct and automatically generate an immutable wrapper and also a "builder" class for incrementally building new instances?
Example input:
struct Foo
{
public int apples;
public int oranges;
public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
Example output:
public class ImmutableFoo // could probably be a struct
{
private Foo snapshot;
internal ImmutableFoo(Foo value) { this.snapshot = value; }
public FooBuilder Builder() { return new FooBuilder(snapshot); }
public int Apples { get { return snapshot.apples; } }
public int Oranges { get { return snapshot.oranges; } }
}
public class FooBuilder
{
private Foo state;
public int Apples { get { return state.apples; } set { state.apples = value; } }
public int Oranges { get { return state.oranges; } set { state.oranges = value; } }
public FooBuilder() { }
internal FooBuilder(Foo toCopy) { state = toCopy.Clone(); }
public ImmutableFoo Build()
{
ImmutableFoo result = new ImmutableFoo(state);
state = state.Clone();
return result;
}
}
Such a "tool" could be an IDE plugin or could generate the new class at run-time using reflection.
The example is in C# but I would be interested in a solution for any statically-typed OO language (Java, Scala, C++ etc.)
Desirable features:
Re-creates methods from the struct in the builder class
Re-creates nondestructive methods from the struct in the immutable class (esp. Equals() and GetHashCode() and any interface methods)
Also generates a IFooReader interface containing read-only properties for each struct member, implemented by both the immutable and the builder.
If a field's class has an immutable equivalent, uses the immutable version in the immutable class (see also How do I create a builder in C# for an object that has properties that are referenc types?) e.g. List -> ReadOnlyCollection or similar.
Alternatively take the builder class as input (where the builder uses automatic properties instead of delegating to a struct.)
Does not require the Clone method to be predefined
"You should not use a tool like this because..." answers are also welcome.
Here are four possible solutions.
1) Use CodeDOM to generate C# or VB code. This would also allow you to use visual studio extensions to generate your code in designer files. Similar to some of the built in tools that visual studio already offers - like the ones that generate wrappers for web service calls etc. Unfortunately I don't know much about extending Visual Studio.
Pros - You can generate source prior to building. This makes it easier to write code against the generated types from any assembly.
Cons - Not language agnostic. You're stuck with the languages that are supported.
2) Use the Mono.Cecil library to analyze your assembly post-build. You can then re-write the assembly with the new types included.
Pros - Language agnostic.
Cons - If you add the types to same assembly in which your structs are defined you won't be able to write code against the generated immutable struct types in the same assembly. If you put the generated types in a new assembly then this is possible.
3) Use PostSharp. I don't know as much about this library so you might not be able to add new types to your assembly but I know you can inject IL into methods. It also has a lot of nice stuff that makes it easy to do this with attributes. So you could do this -
[GenerateImmutable]
struct Foo
{
public int apples;
public int oranges;
public Foo Clone() {return (Foo) base.MemberwiseClone();}
}
Pros - Language agnostic, AOP is easier to do in PostSharp.
Cons - Same as with Mono.Cecil and also not sure if you can generate new types using PostSharp.
4) Use built in Reflection.Emit libraries to generate a new assembly with your immutable types.
Pros - Language agnostic, No 3rd party stuff.
Cons - Must put generated types in new assemblies. Can't add them to the same assembly that the original type is in.
Why bother with the builder?
You have a (nasty) mutable struct, but if you must have it use that directly rather than creating a cumbersome and unnecessary Builder.
It bothers me somewhat that you have sufficient number of these structs for you to feel you need to autogenerate wrappers of this kind. My gut reaction is that you are doing it wrong...
If the purpose of the immutable wrapper is just to store a snapshot then just use something like this:
public struct Snapshot<T> where t : struct
{
private readonly T data;
public Snapshot(T value) { this.data = value; }
public T Data { get { return data; } }
}
The struct passed in is guaranteed to never change again, but you can access all the values on it directly (and modifications on these results happen on the copy created when calling the underlying get_Data function)
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