Click here to Skip to main content
15,919,479 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have checked this problem for years. I have two different structures that I need to pass as parameters to a common function. The two structures have within another structure that is common to both. If the root is dynamic, the values are not assigned in the internal structure.

In the background there is also the problem that instead of having a single structure ref dynamic I have to have two structures because you cannot pass ref struct to ref dynamic or vice versa. Why?

The interior structures are sized although it does not appear in this code.

It does not help me to be told to think things differently because in the common function I have many things that are general to both structures and some things that are different.

C#
public struct St_A
{
  public dynamic MyValue1; 
  public string  MyValue2; 

  public struct St_A1     StProp
  public struct St_COMMON StCommon;
}

public struct St_B
{
  public struct St_COMMON StCommon;
}

public struct St_A1
{
  public dynamic MyValue3; 
  public string  MyValue4; 
}

public struct St_COMMON
{
  public int Value;
}

MyFunction()
{
  struct St_A StA = new St_A();
  struct St_B StB = new St_B();
  dynamic MyRet = Function_Common(true, ref StA, ref StB)
}

public static Function_Common(bool Struct_is_A, ref St_A StA, ref St_B StB)
{
  dynamic MyStruct = null;

  if (Struct_is_A)
    MyStruct = (St_A)StA;
  else
    MyStruct = (St_B)StB;

  // This Works.
  MyStruct.MyValue1 = "10";
  MyStruct.MyValue2 = "10";

  // PROBLEM. It does not produce an error and does not assign the value. If from the 
  // debugger I perform the same action, then it is assigned.
  MyStruct.StProp.MyValue3 = "10";
  MyStruct.StProp.MyValue4 = "10";

  // PROBLEM. It does not produce an error and does not assign the value. If from the 
  // debugger I perform the same action, then it is assigned.
  MyStruct.StCommon.Value = 10;
}


What I have tried:

in al sites of internet.in al sites of internet.
Posted
Updated 23-Sep-19 2:45am
v7

1 solution

Structure types are kept on the stack. The problem with dynamic is that it's not possible to determine the size of the object it's holding, so how far does the code move the stack pointer so one object or function return doesn't overwrite part of your structure? It's not possible.

You're trying to violate just about every point listed in the ref documentation:
Quote:
Ref struct types
Adding the ref modifier to a struct declaration defines that instances of that type must be stack allocated. In other words, instances of these types can never be created on the heap as a member of another class. The primary motivation for this feature was Span<t> and related structures.

The goal of keeping a ref struct type as a stack-allocated variable introduces several rules that the compiler enforces for all ref struct types.

You can't box a ref struct. You cannot assign a ref struct type to a variable of type object, dynamic, or any interface type.
ref struct types cannot implement interfaces.
You can't declare a ref struct as a field member of a class or a normal struct. This includes declaring an auto-implemented property, which creates a compiler generated backing field.
You cannot declare local variables that are ref struct types in async methods. You can declare them in synchronous methods that return Task, Task<tresult> or Task-like types.
You cannot declare ref struct local variables in iterators.
You cannot capture ref struct variables in lambda expressions or local functions.
These restrictions ensure you don't accidentally use a ref struct in a manner that could promote it to the managed heap.

You can combine modifiers to declare a struct as readonly ref. A readonly ref struct combines the benefits and restrictions of ref struct and readonly struct declarations.
 
Share this answer
 
Comments
[no name] 23-Sep-19 9:15am    
Where did you find that information?

I see a great list of things that cannot be done. I want to do something simple that is to pass a structure by reference dynamically, but it doesn't work. It is a technical problem of C# that they have not solved.

Now I have this problem and I can't find a solution other than duplicating hundreds of lines of code for each of the structures.

Any solution?
Dave Kreskowiak 23-Sep-19 10:34am    
Like I said in the answer, in the documentation for the ref keyword.

The problem is not a technical one in C#. It's a technical one with how stacks work and is not possible to "solve".

Instead of using structures, which are value types stored on the stack, convert the structures to classes, which are reference types stored in the managed heap.
[no name] 23-Sep-19 9:18am    
Dave, I have this problem with Sql Server and nobody answers me. I have been working on something for years and if it is not solved, my work will be useless.

Do you know someone who hears what I explain? Thank you

https://social.msdn.microsoft.com/Forums/en-US/4a17a3fd-5074-4b9b-a05b-0eae7e3f44ae/sql-server-2017-transact-problems-microsoft-does-not-respond-can-you-read?forum=transactsql
Dave Kreskowiak 23-Sep-19 10:41am    
Nope. I don't have any clue on that.
[no name] 23-Sep-19 10:44am    
Thanks for your help, did you find the documentation in the same link you gave me?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900