Structure Generics in C# - c#

Please, help me with this problem:
I Try define a structure like this:
unsafe struct sNodo<T>
{
public T info;
public sNodo<T>* sIzq;}
but i get this error: Cannot take the address of, get the size of, or declare a pointer to a managed type sNodo,
how can I fix it?
I'm trying to create a stack "generic" using dynamic memory.
Thank you for your attention

If all you need is to create a generic stack, you don't need unsafe. Just use the normal C# language:
class StackNode<T> {
public T info;
public StackNode<T> next;
}
Why exactly do you feel you need unsafe?
Maybe you're thinking that you need a pointer because the otherwise your type can't have another instance of the same type as a data member. Indeed, in C# if you try to do:
struct Foo {
int data;
Foo next;
}
...the C# compiler will complain about circular struct references and refuse to compile your code (if you don't see why it has to do that, try to figure out how many bytes a Foo object should take up in memory).
But if you try to do the same thing with the class keyword:
class Bar {
int data;
Bar next;
}
...everything works! If you come from a C++ background, where classes and structs are more or less the same thing, this is very puzzling.
The secret is that in C#, structs have value semantics while classes have reference semantics. So the C++, the above two definitions are most similar to:
class Foo {
int data;
Foo next; // This doesn't compile in C++ either.
}
class Bar {
int data;
Bar* next; // But this is ok.
}
This C++ code isn't completely equivalent, of course, but it should give you a basic idea of what to expect.
Bottom line: if you're just learning C#, don't use structs; everything they can do, classes can do too. Once you understand C# semantics, and are sure that the value semantics structs give you can provide you with a performance benefit, and are sure that that performance benefit actually matters to your app, go ahead and use them.

Related

Does a struct make sense to return Data from a function in a structured way? (when is a struct apropriate?)

Intro
So far I am trying to wrap my head around structs. I have found many answers on the Topic "When to use a struct". Most of them are vague such as advice against the use of structs in general, with few exceptions. There are explanations of when to use structs (few examples):
immutable Data
value semantics as opposed to reference semantics
need them in code passing structured data to/from C/C++
Do not use structs unless you need them
But no example code as to when this case actually happens that it makes sense.
probably one of the most well known Questions/Answers is this one:
When should I use a struct rather than a class in C#?
Project structure
class StorageBlock<Type>:
/// this is a storage block. It is not a struct because the data is not immutable and it
/// should be passed by reference
public class StorageBlock<Type>
{
Type[] Data;
/* other stuff */
}
methodBlockSearcher():
public (StorageBlock<Type> FoundBlock, int FoundIndex) SearchBlock(Type searchForThisElement)
{
StorageBlock<Type> found = Blocks.Find(searchForThisElement);
int index = Array.IndexOf(found.Data, searchForThisElement);
return (found,index);
}
caller example:
(StorageBlock<Type> FoundBlock, int FoundIndex) searchResult = SearchBlock(searchElement);
/* process SearchResult(s) */
Questions
I wonder if it makes sense to convert (StorageBlock<Type> FoundBlock, int FoundIndex) searchResult to a struct. The search result should be immutable. It is only there to provide a return from specific indexing operations.
something like this:
struct BlockIndex
{
StorageBlock<Type> Block;
int Index;
}
Because a struct is a DataType, not a reference type, I also wonder if BlockIndex.Block (which is a class) will be a reference to the instance of block or a copy of the found block.
It seems like you're comparing structs to tuples (which are compiled to ValueTuple, not Tuple), not structs to classes (which is the more common question and the context of the original suggestions). Defining tuples with that syntax is a more recent construct in C# so I don't know that there is a best practice yet on whether to explicitly define a struct or use a tuple.
Behind-the-scenes, tuples are implemented as ValueTuple structs, so there should be minimal (if any) performance difference by defining a struct. It's more for coding convenience than performance.
As a pragmatist, I would say to continue using tuples until you have a measurable problem.
The search result should be immutable
This is the only thing I see that would make me consider defining a readonly struct, since ValueTuple is not immutable by default.
Because a struct is a [value type], not a reference type, I also wonder if BlockIndex.Block (which is a class) will be a reference to the instance of block or a copy of the found block.
It will still be a reference. Reference types do not cease to be reference types just because they're a property of a struct. The value of the reference will be carried along with the struct just like an integer would.

How can I ensure T is serializable in a fixed number of bytes?

I'm writing a generic DataStructure<T> which persists on the disk, and I need to write it such that T is guaranteed to be serializable in a fixed number of bytes. For example, int and char should be accepted, but string or int[] should not be. Likewise, a struct with a string member is not acceptable, but an unsafe struct with a fixed char array is.
I could write a runtime test in the initializer using reflection and sizeof to test each member, but that seems like a terrible hack. Is there any efficient and (relatively) safe way to do this?
There is no way to statically support a generic parameter which only have a fixed specific size. Constraints are limited to interfaces, ref / struct, base class and new.
What you can do though is use static factory methods to limit the uses of the generic to a known finite set of types which are suitable. For example
class DataStructure<T> {
private DataStructure(T value) {
...
}
}
static class DataStructure {
public static DataStructure<int> Create(int i) {
return new DataStructure<int>(i);
}
public static DataStructure<char> Create(char c) {
return new DataStructure<char>(c);
}
}
This is limiting though because it requires you to list all comparable types ahead of time. If you want a more flexible solution that works with user defined types you'll need to implement a runtime check.
public static DataStructure<T> Create<T>(T value) {
RuntimeVerification(typeof(T));
return new DataStructure<T>(value);
}
Every valuetype that directly or indirectly contains only value types, but no reference types has a limited size. The only way to test that is at runtime using reflection.
If that is a good idea is a different question, and I'd say it's not a good idea. Serializing the raw data of a type is generally a bad idea IMO.

C# Managed Unmanaged code

I'm trying to understand managed/unmanaged code as it pertains to structs and classes. I have a struct with a property of another struct but its a pointer declaration as in:
struct StateInfo
{
Bitboard board;
StateInfo* previous;
}
I'm converting a C++ project to C#. Anyways, this doesn't work because Bitboard is a class. The error I get is something to the fact that pointers cannot be declared on managed types. If I take out Bitboard from the struct, it's fine. I need it though so I changed Bitboard from a class to a struct, and all is good. I'm not sure what's up? Any ideas?
You probably don't even want a struct. Instead:
class StateInfo
{
Bitboard board;
StateInfo previous;
}
In C#, a struct is a value type. For instance, int is a struct. They should typically be used for things which are entirely described by their value.
I suggest you read about blittability.
Blittable types have the same binary representation in managed and unmanaged code, and you need to represent them the same way if you want pointers to make sense.
Essentially, in c# all objects are automatically a pointer and do not need to be released.
Try reading some transitional articles about moving from C++ to C#
C++ -> C#: What You Need to Know to Move from C++ to C#

What is the Equivalent of "object of C# " in VC++?

In C# we have a datatype object which can hold any type of data. Same thing I want to achieve in VC++. Can anyone kindly let me know VC++ equivalent of "Object of C#".
IN C#, in the calling appl program (say call.cs)
object ob=null;
ob=(object)str;
funct(ref ob);
Here str is empty string.
This thing I want to achieve in VC++. So I need to create VC++ equivalent of object.
I am sure we need to use pointers as ref's equivalent??
There isn't one. C++ doesn't have a unified type hierarchy like .NET languages have.
The closest you can get is a void* (pointer-to-void), which can point to any type of object. You should avoid void*s like the plague, though; once you start using them you lose any and all type safety.
As other commentators have said, C++ does not have a common base-class for every object. Theoretically, you could create your own and derive everything from it:
class Object
{
protected:
Object(){};
virtual ~Object(){};
public:
virtual std::string toString() const {return("");};
}; // eo class Object
This, however, won't help you with integral types such as int, short. You'd have to make your own:
class Int : public Object
{
private:
int m_nVal;
public:
Int(int _val = 0) : m_nVal(_val){};
Int(const Int& _rhs) : m_nVal(_rhs.m_nVal){};
virtual ~Int(){};
// operators
operator int() const {return(m_nVal);}
bool operator == (const Int& _rhs) const {return(m_nVal == _rhs.m_nVal);};
bool operator == (int _val) const {return(m_nVal == _val);};
Int& operator = (const Int& _rhs) {m_nVal = _rhs.m_nVal; return(*this);}:
Int& operator = (int _val) {m_nVal = _val; return(*this);};
// .... and all the other operators
// overrides
virtual std::string toString() const
{
std::ostringstream oss;
oss << m_nVal;
return(oss.str());
};
}; // eo class Int
You'd then have to do this for all the other types you want to use. Once done you can pass them around as if they were ints, bools, longs etc (thanks to operator overloading). A better method would be to use a template class for the integral types:
template<class T> class IntegralType : public Object
{
private:
T m_Val;
public:
// rest of class looks the same
}; // eo class IntegralType<>
Then typedef them away:
typedef IntegralType<int> Int;
typedef IntegralType<short> Short;
typedef IntegralType<long> Long;
Even using a template-class like this to take the leg-work out of it, you'd still need a specialisation for strings/bools. implementing operator ++ on IntegralType<> will work fine for numbers, but is going to throw up on std::string.
If you went the template route, you've now got "Object", integral types and some specialisations for strings, bools. But to mimick .NET even more, you probably want to introduce interfaces for comparisons:
template<class T> class IEquitable
{
public:
virtual Equals(T _other) = 0;
}; // eo class IEquitable<>
That can easily be plumbed in to your IntegralType<> classes and the specialisations.
But as another commentator pointed out, why would you? boost::any is useful if you're trying to do something like a Tuple which has a name and a value of an arbitrary type. If you need to build a collection of these then there is something fundamentally wrong with your design. For example, in all my coding in C# I have never had to write:
List<Object> list = new List<Object>();
There may have been:
List<Vehicle> list;
List<Employee> List;
Dictionary<string, Alien> aliens;
But never anything at the Object level. Why? Well apart from calling ToString() on it, or perhaps doing some risky casting, why would you want to? Generics exist in programming so that we do not have to have lists of objects (or in the case of C++, void*).
So there you have it. The above shows how you might have objects and integral types working kind of like C#, and I've missed a chunk of stuff out. Now it's time to look at your design and decide if that's what you really need to do.
There's nothing built into the language. Usually, wanting it at all indicates that your design isn't very well thought out, but if you can't figure out any alternative, you might consider (for one example) Boost any.
The <comutil.h> header contains a handy wrapper for VARIANT. Takes care of proper initialization and cleanup.
#include <comutil.h>
#ifdef _DEBUG
# pragma comment(lib, "comsuppwd.lib")
#else
# pragma comment(lib, "comsuppw.lib")
#endif
...
_variant_t arg = L"some string";
someComPtr->func(&arg);
There isn't anything in your code snippet that would help me help you figuring out how to obtain the COM interface pointer. Start a new question about that if you have trouble.
The alternative for you is to look at System.Runtime.InteropServices.GCHandle, which allows you to find the managed object from unmanaged code, but in any way you will end up with nasty and risky type casts and you need to be really careful to keep somewhere a reference to the managed object as it might get garbage-collected if there is only a reference in unmanaged code.

Are methods also serialized along with the data members in .NET?

The title is obvious, I need to know if methods are serialized along with object instances in C#, I know that they don't in Java but I'm a little new to C#. If they don't, do I have to put the original class with the byte stream(serialized object) in one package when sending it to another PC? Can the original class be like a DLL file?
No. The type information is serialized, along with state. In order to deserialize the data, your program will need to have access to the assemblies containing the types (including methods).
It may be easier to understand if you've learned C. A class like
class C
{
private int _m;
private int _n;
int Meth(int p)
{
return _m + _n + p;
}
}
is essentially syntactic sugar for
typedef struct
{
int _m;
int _n;
// NO function pointers necessary
} C;
void C_Meth(C* obj, int p)
{
return obj->_m + obj->_n + p;
}
This is essentially how non-virtual methods are implemented in object-oriented languages. The important thing here is that methods are not part of the instance data.
Methods aren't serialized.
I don't know about your scenario, but putting in a library (assembly / dll) and using that in the other end to deserialize gets you all.
Ps. you probably should create some ask some more questions with the factors involved in your scenario. If you are intending to dynamically send & run the code, you can create awful security consequences.
I was confused when .NET first came up with serialization. I think it came from the fact that most books and guides mention that it allows you to serialize your 'objects' as XML and move them around, the fact is that you are actually hydrating the values of your object so you can dehydrate them latter. at no point your are saving your whole object to disk since that would require the dll and is not contained in the XML file.

Categories

Resources