I'm using .NET 3.5. We have some complex third-party classes which are automatically generated and out of my control, but which we must work with for testing purposes. I see my team doing a lot of deeply-nested property getting/setting in our test code, and it's getting pretty cumbersome.
To remedy the problem, I'd like to make a fluent interface for setting properties on the various objects in the hierarchical tree. There are a large number of properties and classes in this third-party library, and it would be too tedious to map everything manually.
My initial thought was to just use object initializers. Red, Blue, and Green are properties, and Mix() is a method that sets a fourth property Color to the closest RGB-safe color with that mixed color. Paints must be homogenized with Stir() before they can be used.
Bucket b = new Bucket() {
Paint = new Paint() {
Red = 0.4;
Blue = 0.2;
Green = 0.1;
}
};
That works to initialize the Paint, but I need to chain Mix() and other methods to it. Next attempt:
Create<Bucket>(Create<Paint>()
.SetRed(0.4)
.SetBlue(0.2)
.SetGreen(0.1)
.Mix().Stir()
)
But that doesn't scale well, because I'd have to define a method for each property I want to set, and there are hundreds of different properties in all the classes. Also, C# doesn't have a way to dynamically define methods prior to C# 4, so I don't think I can hook into things to do this automatically in some way.
Third attempt:
Create<Bucket>(Create<Paint>().Set(p => {
p.Red = 0.4;
p.Blue = 0.2;
p.Green = 0.1;
}).Mix().Stir()
)
That doesn't look too bad, and seems like it'd be feasible. Is this an advisable approach? Is it possible to write a Set method that works this way? Or should I be pursuing an alternate strategy?
Does this work?
Bucket b = new Bucket() {
Paint = new Paint() {
Red = 0.4;
Blue = 0.2;
Green = 0.1;
}.Mix().Stir()
};
Assuming Mix() and Stir() are defined to return a Paint object.
To call methods that return void, you can use an extension method that will allow you to perform additional initialization on the object you pass in:
public static T Init<T>(this T #this, Action<T> initAction) {
if (initAction != null)
initAction(#this);
return #this;
}
Which could be used similar to Set() as described:
Bucket b = new Bucket() {
Paint = new Paint() {
Red = 0.4;
Blue = 0.2;
Green = 0.1;
}.Init(p => {
p.Mix().Stir();
})
};
I would think of it this way:
You essentially want your last method in the chain to return a Bucket. In your case, I think you want that method to be Mix(), as you can Stir() the bucket afterwards
public class BucketBuilder
{
private int _red = 0;
private int _green = 0;
private int _blue = 0;
public Bucket Mix()
{
Bucket bucket = new Bucket(_paint);
bucket.Mix();
return bucket;
}
}
So you need to set at least one colour before you call Mix(). Let's force that with some Syntax interfaces.
public interface IStillNeedsMixing : ICanAddColours
{
Bucket Mix();
}
public interface ICanAddColours
{
IStillNeedsMixing Red(int red);
IStillNeedsMixing Green(int green);
IStillNeedsMixing Blue(int blue);
}
And let's apply these to the BucketBuilder
public class BucketBuilder : IStillNeedsMixing, ICanAddColours
{
private int _red = 0;
private int _green = 0;
private int _blue = 0;
public IStillNeedsMixing Red(int red)
{
_red += red;
return this;
}
public IStillNeedsMixing Green(int green)
{
_green += green;
return this;
}
public IStillNeedsMixing Blue(int blue)
{
_blue += blue;
return this;
}
public Bucket Mix()
{
Bucket bucket = new Bucket(new Paint(_red, _green, _blue));
bucket.Mix();
return bucket;
}
}
Now you need an initial static property to kick off the chain
public static class CreateBucket
{
public static ICanAddColours UsingPaint
{
return new BucketBuilder();
}
}
And that's pretty much it, you now have a fluent interface with optional RGB parameters (as long as you enter at least one) as a bonus.
CreateBucket.UsingPaint.Red(0.4).Green(0.2).Mix().Stir();
The thing with Fluent Interfaces is that they're not that easy to put together, but they are easy for the developer to code against and they are very extensible. If you want to add a Matt/Gloss flag to this without changing all of your calling code, it's easy to do.
Also, if the provider of your API changes everything underneath you, you only have to rewrite this one piece of code; all the callin code can remain the same.
I would use the Init extension method because U can always play with the delegate.
Hell You can always declare extension methods that take up expressions and even play up with the expresions (store them for later, modify, whatever)
This way You can easily store default grups like:
Create<Paint>(() => new Paint{p.Red = 0.3, p.Blue = 0.2, p.Green = 0.1}).
Init(p => p.Mix().Stir())
This Way You can use all the actions (or funcs) and cache standard initializers as expression chains for later?
If you really want to be able to chain property settings without having to write a ton of code, one way to do this would be to use code generation (CodeDom). You can use Reflection to get a list of the mutable properties, the generate a fluent builder class with a final Build() method that returns the class you're actually trying to create.
I'm going to skip over all the boilerplate stuff about how to register the custom tool - that's fairly easy to find documentation on but still long-winded and I don't think I'd be adding much by including it. I will show you what I'm thinking of for the codegen though.
public static class PropertyBuilderGenerator
{
public static CodeTypeDeclaration GenerateBuilder(Type destType)
{
if (destType == null)
throw new ArgumentNullException("destType");
CodeTypeDeclaration builderType = new
CodeTypeDeclaration(destType.Name + "Builder");
builderType.TypeAttributes = TypeAttributes.Public;
CodeTypeReference destTypeRef = new CodeTypeReference(destType);
CodeExpression resultExpr = AddResultField(builderType, destTypeRef);
PropertyInfo[] builderProps = destType.GetProperties(
BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo prop in builderProps)
{
AddPropertyBuilder(builderType, resultExpr, prop);
}
AddBuildMethod(builderType, resultExpr, destTypeRef);
return builderType;
}
private static void AddBuildMethod(CodeTypeDeclaration builderType,
CodeExpression resultExpr, CodeTypeReference destTypeRef)
{
CodeMemberMethod method = new CodeMemberMethod();
method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
method.Name = "Build";
method.ReturnType = destTypeRef;
method.Statements.Add(new MethodReturnStatement(resultExpr));
builderType.Members.Add(method);
}
private static void AddPropertyBuilder(CodeTypeDeclaration builderType,
CodeExpression resultExpr, PropertyInfo prop)
{
CodeMemberMethod method = new CodeMemberMethod();
method.Attributes = MemberAttributes.Public | MemberAttributes.Final;
method.Name = prop.Name;
method.ReturnType = new CodeTypeReference(builderType.Name);
method.Parameters.Add(new CodeParameterDeclarationExpression(prop.Type,
"value"));
method.Statements.Add(new CodeAssignStatement(
new CodePropertyReferenceExpression(resultExpr, prop.Name),
new CodeArgumentReferenceExpression("value")));
method.Statements.Add(new MethodReturnStatement(
new CodeThisExpression()));
builderType.Members.Add(method);
}
private static CodeFieldReferenceExpression AddResultField(
CodeTypeDeclaration builderType, CodeTypeReference destTypeRef)
{
const string fieldName = "_result";
CodeMemberField resultField = new CodeMemberField(destTypeRef, fieldName);
resultField.Attributes = MemberAttributes.Private;
builderType.Members.Add(resultField);
return new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), fieldName);
}
}
I think this should just about do it - it's obviously untested, but where you go from here is that you create a codegen (inheriting from BaseCodeGeneratorWithSite) that compiles a CodeCompileUnit populated with a list of types. That list comes from the file type you register with the tool - in this case I'd probably just make it a text file with a line-delimited list of types that you want to generate builder code for. Have the tool scan this, load the types (might have to load the assemblies first), and generate bytecode.
It's tough, but not as tough as it sounds, and when you're done you'll be able to write code like this:
Paint p = new PaintBuilder().Red(0.4).Blue(0.2).Green(0.1).Build().Mix.Stir();
Which I believe is almost exactly what you want. All you have to do to invoke the code generation is register the tool with a custom extension (let's say .buildertypes), put a file with that extension in your project, and put a list of types in it:
MyCompany.MyProject.Paint
MyCompany.MyProject.Foo
MyCompany.MyLibrary.Bar
And so on. When you save, it will automatically generate the code file you need that supports writing statements like the one above.
I've used this approach before for a highly convoluted messaging system with several hundred different message types. It was taking too long to always construct the message, set a bunch of properties, send it through the channel, receive from the channel, serialize the response, etc... using a codegen greatly simplified the work as it enabled me to generate a single messaging class that took all of the individual properties as arguments and spit back a response of the correct type. It's not something I would recommend to everyone, but when you're dealing with very large projects, sometimes you need to start inventing your own syntax!
Related
I need to replace a method with a call to a method with the same signature so that I can essentially replace the original method with a new method. Currently, I have the code below, which works, but when I try to patch the method again, it simply does nothing. I'm not sure if that's because Harmony doesn't like when I try to transpile it twice, or something else, either way it prevents me from repeatedly redirecting the original method.
// this is factored out of Transpiler() because yield return reasons
private static IEnumerable<CodeInstruction> TranspilerIterator(IEnumerable<CodeInstruction> instructions,
MethodBase original) {
var name = original.Name;
var par = original.GetParameters();
var method = newGuiType.GetMethod(name, (BindingFlags) FLAGS);
Console.WriteLine($"{name} == null == {method == null}");
if ((method.CallingConvention & CallingConventions.HasThis) != 0)
yield return new CodeInstruction(OpCodes.Ldarg_0);
for (var i = 0; i < par.Length; i++)
yield return new CodeInstruction(OpCodes.Ldarg_S, par[i].Position + 1);
yield return new CodeInstruction(OpCodes.Call, method);
yield return new CodeInstruction(OpCodes.Ret);
}
which is called by this:
private void DoPatches() {
Logger.Debug("Performing patches.");
var methods = oldGuiType.GetMethods((BindingFlags) FLAGS);
var t = this.GetType().GetMethod("Transpiler", BindingFlags.NonPublic | BindingFlags.Static);
for (var i = 0; i < methods.Length; i++) {
var name = methods[i].Name;
Logger.Debug($"Transpiling {name}");
harmony.Patch(methods[i], transpiler: new HarmonyMethod(t));
}
}
I can't use a prefix because I need to know the signature to get the args in a prefix, and I don't know the signature.
I know there are other libraries to make essentially this, but the game I'm modding ships with Harmony so I don't have to ship a whole lib with my very small mod.
For every change to an original method (like adding or removing a transpiler) Harmony will recalculate the replacement method by doing this (in pseudo code):
original_IL -> transpiler1 -> transpiler2 -> ... -> transpiler_n -> replacement_IL
where transpiler 1..n are all active transpilers. It then build the replacement by (roughly) structuring it like this:
// Note: the following is very simplified and only used to illustrate
// the difference between prefix/postfix and a transpiler.
REPLACEMENT()
{
if (Prefix_1() == false) return
// ...
if (Prefix_n() == false) return
// replacement_IL_here
Postfix_1()
// ...
Postfix_n()
}
Internally, Harmony has to therefore keep track of all patches and since those can be from different Assemblies it would need to serialize/deserialize state - which is in principle impossible if you have arbitrary state. Therefore, it only stores the simplest key for each patch possible: its MethodInfo which must be a static method.
As a result you cannot apply the same patch multiple times. It makes little sense since you could easily put all your code into one patch anyway.
For this application, ie updating a method to a newer method with an identical signature, Memory.DetourMethod(MethodBase original, MethodBase replacement) did what I needed.
// assuming newType is just a newer version of oldType
var newMethod = newType.getMethod("SomeMethod");
var oldMethod = oldType.getMethod("SomeMethod");
Memory.DetourMethod(oldMethod, newMethod);
This code effectively replaces the old method with the new method. The way it actually works is a bit more complicated.
I'm generating a random number from 1-1000. I have 200 functions named function1, function4, function 10, function 11, etc. What I would like to do is execute a specific function depending on if the number generated requires a function, and ignore it if not.
My first thought was to create an int[] containing all of the values that would trigger a function, and if the int[] contains the random number to use if statements to figure out what the number is. I'm concerned that it must be a really crude solution to an easy problem though.
I know the "best way" to do something is subjective, but is there a better way to accomplish this?
UPDATE: As per comments, I should probably have started out by pointing out that doing this for 200 functions is probably a good sign that there is some serious issue in your design. This is probably an XY question where you are trying to solve a problem in some crazy way and asking about your intended solution instead of asking about the problem itself.
That said I'll leave the original answer because it's still good advice when mapping a reasonable amount of function calls that can/will change during the life cylce of your app or dynamically as the code runs.
I won't get into why you are doing this, but I'll try to at least point you in the right direction so this doesn't become a complete nightmare when you need to modify/expand behavior:
You can map numbers to function calls using delegates and a dictionary. Assuming your functions take no arguments and return void you'd do:
var functionsMap = new Dictionary<int, Action>();
//map functions
var r = getSomeRandomNumber();
if (functions.TryGetValue(r), out var a)
a(); //invoke function
Mapping functions is simply adding keys and values:
functionsMap.Add(1, () => function1());
functionsMap.Add(3, () => function3());
//etc.
If your functions take arguments or return values, you'd use the adequate delegate: Action<T>, Func<T1, T2> etc.
You can use reflection to invoke appropriate method:
Type exampleType = exampleObject.GetType();
MethodInfo exampleMethod = exampleType.GetMethod(methodName);
exampleMethod.Invoke(this, null);
Where methodName can be created using your random number.
Without commenting on the wisdom of having 200 functions named the way yours are, you can use reflection to determine whether a given functionX() exists, like so:
public void ExecuteDynamicMethod(int number)
{
// Modify these two lines with your app's dll/exe and class type:
Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
Type type = assembly.GetType("YourClassType");
if (type != null)
{
MethodInfo methodInfo = type.GetMethod("function" + number);
if (methodInfo != null)
{
object classInstance = Activator.CreateInstance(type, null);
methodInfo.Invoke(classInstance, null); // null = "no function arguments"
}
}
}
This can then be called for a given value like
ExecuteDynamicMethod(14);
See this SO answer for the inspiration behind this.
Reflection can be used for this purpose. I want to give and keep below example for not only the objective of the question but also for future reference. Also, of course that many function is not good but below code shows the approach that can work with many functions if they have similar name (like starting with "function" keyword).
Assume below is Methods.cs
using System;
using System.Reflection;
namespace YourMethodNamespace
{
public class YourMethodClass
{
public void function1()
{
Console.WriteLine("Function-1");
}
public void function2()
{
Console.WriteLine("Function-2");
}
...
public void function200()
{
Console.WriteLine("Function-200");
}
public static void invokeMethodsDynamically(int randomNumber){
Type yourClassType = typeof(YourMethodClass);
ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(Type.EmptyTypes);
object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{});
//If the constructor has parameters, then we can pass them by this way. Like below;
/*ConstructorInfo yourClassConstructorInfo = yourClassType.GetConstructor(new[]{typeof(int)});
object yourClassObject = yourClassConstructorInfo.Invoke(new object[]{3});
*/
MethodInfo[] methodInfoArr = yourClassType.GetMethods();
foreach(MethodInfo methodInfo in methodInfoArr){
if(methodInfo.Name == "function" + randomNumber){
methodInfo.Invoke(yourClassObject, null);
}
}
}
}
}
Let's say below is Program.cs
using System;
using YourMethodNamespace;
namespace YourProgramNamespace
{
public class YourProgramClass
{
public static void Main()
{
Random random = new Random();
int randomNumber = random.Next(1, 201);
//If Methods.cs is in another Assembly
/*string pathToDllAssembly = #"Domain.dll";
Assembly dllAssembly = Assembly.LoadFrom(pathToDllAssembly);
Type methodsClassType = dllAssembly.GetType("YourMethodNamespace.YourMethodClass");
ConstructorInfo methodClassConstructorInfo = methodsClassType.GetConstructor(Type.EmptyTypes);
object methodsClassObject = methodClassConstructorInfo.Invoke(new object[]{});
MethodInfo methodInfo = methodsClassType.GetMethod("invokeMethodsDynamically");
methodInfo.Invoke(methodsClassObject, new object[]{randomNumber});
*/
YourMethodClass.invokeMethodsDynamically(randomNumber, null);
}
}
}
Also for testing and observing, below link can be used.
https://repl.it/#erdsavasci/ReflectionTest
I would like to implement what I know as a CVAR System, I'm not entirely sure on what the official name of it is (if any).
It's essentially a system used in some programs and video games, where a user can pull down a console and input a command, such as "variable 500" to set that variable to 500. Instances of this can be found in any Half-Life game, Doom and Quake games, and many more. The general idea seems to be to hide the underlying architecture, but still allow protected access, for instance, one may be able to view the value for, say, gravity, but not change it. Some of these values may also be functions, for instance, a user may be able to input "create " to create an enemy type at their location, or some other location specified.
Looking through the Half Life 2 SDK, and from what I remember on the GoldSrc SDK, it seems like they at least implemented "flagging" of sorts, where certain commands would only work under certain conditions, such as if another value was set, or if the user has some permission level.
My initial thought was to create a Dictionary, or an object similar to do that, and use that to bind string values to function delegates, as well as keep a "protection" level of sorts, to limit usage of certain commands. However, this seems rather cumbersome, as I believe I would have to go through and add in a new entry manually for each value or function I wanted to implement. I also don't know if this would give me the control level I'm looking for.
I believe ideally what I would like would be a CVAR System class, as well as a Register function that can take it say, a variable/function delegate, a string to access it, and whatever protection level I need. This way I can add what I need as I see them, so everything is still in it's related classes and files.
I'm really just looking for some ideas here, so my questions are:
Has anyone ever done something like this before, and if so, how?
Would my implementation work? (Theoretically, if not, can you think of a better way?)
If someone is more knowledgeable with how one of the previously mentioned titles does it, can you elaborate on that a bit? It seems to be hard to find documentation on them.
I'm not really looking for specific code, just more of structuring design. And it doesn't have to be "commercial" or work just like another, I just need something to get me going.
Were you thinking about something like this?
class CVAR
{
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float gravity = 0.1f;
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float friction = 0.1f;
[ProtectionLevel(CVARFlags.ReadOnly)]
private string serverVersion = "x.x.x";
public void SetCVARValue(string commandLine) {
string cvarName = GetCvarName(commandLine); // parse the cmd line and get the cvar name from there
object cvarValue = GetCvarValue(commandLine); // parse the value from the string
FieldInfo field = typeof(CVAR).GetField(cvarName);
object[] attributes = field.GetCustomAttributes(typeof(ProtectionLevel), false);
if(attributes.Length > 0) {
ProtectionLevelAttribute attr = (ProtectionLevelAttribute)attributes[0];
if(attr.CheckConditions(World.Instance)) {
field.SetValue(this, cvarValue);
} else {
// error report
}
}
}
}
You could write a parser that looks for commands like
/object_property value
/object_method arg1 arg2
A dictionary, like you suggested, could map those strings to properties and functions. The creation of the dictionary could be done dynamically using reflection by looping through eligible objects, taking their public methods and accessors, and generating a string for them.
Then the dictionary could be mapped in a class for convenience and error checking.
For the methods, the dictionary values could be delegates that take 0..n arguments, for the properties/fields, you will need to be able to some data binding between your actual fields and the dictionary value. UNLESS, your objects themselves refer to the dictionaries for their values, in which case the values only live in place.
To do so, you could simply register your properties using reflection in the object constructor, then call the dictionary in your properties.
[Flags]
public enum CVarAccessibilities
{
Settable,
Gettable
}
public class CVar<T>
{
public CVarAccessibilities Accessibility { get; set; }
T val;
public T Value {
get { return val; }
set
{
if (!Accessibility.HasFlag(CVarAccessibilities.Settable))
return; // just don't set it, maybe print some warning
val = value;
}
}
}
public static class CVarRegistry
{
static Dictionary<string, Object> CVars;
static CVarRegistry { /* use reflections to initialize the dictionary */ }
public static T GetValue<T>(Type owner, string paramName)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
return (T)cvar.Value;
}
public static void SetValue<T>(Type owner, string paramName, T value)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
cvar.Value = value;
}
}
public class MyObject
{
public static int MyRegisteredValue
{
get { return Global.CVarRegistry.GetValue<int>(typeof(MyObject), "MyRegisteredValue"); }
set { Global.CVarRegistry.SetValue(typeof(MyObject), "MyRegisteredValue"); }
}
}
Hope that helps!
This is more commonly known as 'tweak' variables.
Good discussion here: https://gamedev.stackexchange.com/questions/3631/tweaking-and-settings-runtime-variable-modification-and-persistence
I am sure am messing around with a lot of casting and such in this code below. It seems like there should be a smoother way. I'm basically trying to use a builder method (CreateNewPattern) to handle creating new objects of the passed sub-class type (by the CreateNewCircularPattern and CreateNewLinePattern methods). I presently only have two sub-classed types CircularHolePattern and SingleLineHolePattern that inherit from HolePattern, but I expect to have more as my app grows.
Is this a place for using a delegate or a lambda? It know nothing about them, so please be as specific as possible with and code suggestions.
private CircularHolePattern CreateNewCircularPattern()
{
var CreatedPattern = CreateNewPattern(typeof(CircularHolePattern));
return (CircularHolePattern)CreatedPattern;
}
private SingleLineHolePattern CreateNewLinePattern()
{
var CreatedPattern=CreateNewPattern(typeof(SingleLineHolePattern));
return (SingleLineHolePattern)CreatedPattern;
}
private HolePattern CreateNewPattern(Type PatternTypeToCreate)
{
var NewHolePattern = (HolePattern)Activator.CreateInstance(PatternTypeToCreate);
NewHolePattern.PatternName = "Pattern #" + (HolePatterns.Count + 1).ToString();
this.AddPattern(NewHolePattern);
this.SetActivePattern(NewHolePattern);
return NewHolePattern;
}
I suspect you want generics:
private T CreateNewPattern<T>() where T : HolePattern, new()
{
var newHolePattern = new T();
newHolePattern.PatternName = "Pattern #" +
(HolePatterns.Count + 1).ToString();
this.AddPattern(newHolePattern);
this.SetActivePattern(newHolePattern);
return newHolePattern;
}
private SingleLineHolePattern CreateNewLinePattern() {
return CreateNewPattern<SingleLineHolePattern>();
}
private CircularHolePattern CreateNewCircularPattern() {
return CreateNewPattern<CircularHolePattern>();
}
The T is the generic-type-argument; the type we want to create. The where says "it must be HolePattern or a sub-type, and it must have a public parameterless constructor" - this lets us use new T() to create a new instance of it, and access all members of HolePattern against such instances (such as PatternName). This also allows us to call the methods that accept a HolePattern as an argument.
For one, you could reduce the Create...Pattern methods to
private CircularHolePattern CreateNewCircularPattern()
{
return CreateNewPattern(typeof(CircularHolePattern));
}
Another suggestion might be to only work in abstractions. For example, only return HolePattern types from the Create...Pattern methods instead of their concrete types such as CircularHolePattern. You are casting them down to HolePattern in any case.
So, CreateNewCircularPattern becomes
private HolePattern CreateNewCircularPattern()
{
return CreateNewPattern(typeof(CircularHolePattern));
}
I have 2 objects from the same type and i would like to shallow copy one state to the other. In C++ i have memcpy which is great. How can i do it in C#? The MemberwiseClone() is not good enough because it creates & returns a new object and i like to copy to an existing object. I thought of using reflection but i'm afraid it will be too slow for production code. I also thought of using one of the .Net serializers but i think they also create object rather than setting an existing one.
My Use Case:
I have a template object (class not struct) which needs to be updated by one of its instances (objects made of this template)
Any ideas?
In C# (and in C++ too), there is no difference between "new object" and "a copy of existing object" as long as all their members equal to each other.
Given:
Int32 a = 5;
, both operations:
Int32 b = 5;
Int32 b = a;
yield the same result.
As stated in MSDN reference:
The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object.
If a field is a value type, a bit-by-bit copy of the field is performed.
If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.
, i.e. it does just the same as memcpy() in C++
[edit] regarding your clarification:
As I understand, you have N objects, each has a (direct) reference to the template object. You want to write back to the template so all objects "see" these changes.
Suggestion: imlement a template broker.
class TemplateProvider
{
public MyData Template { get; set; }
}
Instead of passing the template, pass the template provider to the objects.
to simplyfy the syntax in the components, you can add a (private/internal?) property
MyData Template { get { return m_templateProvider.Template; } }
void UpdateTemplate() { m_templateProvider.Template =
(MyData) this.MemberwiseClone(); }
The template provider also simplifies locking in multithreaded scenarios.
In short, no way unless you do it yourself. But why not create a new object if you override all properties anyway?
memcopy and similar low level constructs are not supported since they undermine guarantees made by the environment.
A shallow copy for structs is made by assignment. For classes, MemberwiseClone is the method to do that - but as you say that creates a new object.
There is no built in way for that, and as it potentially breaks encapsulation it should be used with care anyway.
You could build a generic routine using reflection, but whether it works or not depends on the class itself. And yes, ti will be comparedly slow.
What's left is supporting it by a custom interface. You can provide a generic "Shallow Copy" routine that checks for the interface and uses that, and falls back to reflection when it doesn't. This makes the functionality available generally, and you can optimize the classes for which performance matters later.
I guess you could just do something like:
YourObjectType A = new YourObjectType();
YourObjectType B = a.MemberwiseClone();
This will create a new object inside the MemberwiseClone method an make the B object reference it. I guess it serves your purposes.
Assignment of one struct to another, for all intents and purposes, works exactly like memcpy in C++ on POD objects.
If you feel that this doesn't apply in your situation then I can assure you that your C++ code was not standard-conforming (i.e., contained bugs in the form of undefined behaviour). Please specify (in the question) what effect you want to achieve. This will be more useful than talking about replicating undefined behaviour in another language.
namespace WindowsFormsApplication7
{
[Serializable] // just put this in your class
class Mate
{
public string SomeProperty { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var mA = new Mate();
mA.SomeProperty = "Hey";
var vf = new BinaryFormatter();
var ns = new MemoryStream();
vf.Serialize(ns, mA);
byte[] vytes = ns.ToArray();
var vfx = new BinaryFormatter();
var nsx = new MemoryStream();
nsx.Write(vytes, 0, vytes.Length);
nsx.Seek(0, 0);
var mB = (Mate)vfx.Deserialize(nsx);
mA.SomeProperty = "Yo";
MessageBox.Show(mA.SomeProperty); // Yo
MessageBox.Show(mB.SomeProperty); // Hey
}
}
}
C# / .Net memcpy equivalent is Buffer.MemoryCopy .
void MemoryCopy (void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy);
https://learn.microsoft.com/en-us/dotnet/api/system.buffer.memorycopy?view=net-5.0
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("lastname", typeof(string));
dt.Columns.Add("firstname", typeof(string));
dt.Rows.Add("lennon", "john");
dt.Rows.Add("mccartney", "paul");
var ms = new MemoryStream();
var bf = new BinaryFormatter();
bf.Serialize(ms, dt);
byte[] bytes = ms.ToArray();
var bfx = new BinaryFormatter();
var msx = new MemoryStream();
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
// doesn't just copy reference, copy all contents
var dtx = (DataTable)bfx.Deserialize(msx);
dtx.Rows[0]["lastname"] = "Ono";
// just copy reference
var dty = dt;
dty.Rows[0]["lastname"] = "Winston";
MessageBox.Show(dt.Rows[0]["lastname"].ToString()); // Winston
MessageBox.Show(dtx.Rows[0]["lastname"].ToString()); // Ono
MessageBox.Show(dty.Rows[0]["lastname"].ToString()); // Winston
}
}
}