Making elements changeable from references - c#

So! I've got a C# array.
And I've got a function that returns an element from the array, so the data from that reference can be accessed. Yay!
It would be really super awesome convenient if changing that reference then affected that original element in the array. Is this what static variables do? Is there a way to do it? How to do? For example:
Function A finds an item:
public TutorialPopupBehavior GetBehavior(string behaviorName) {
foreach(TutorialPopupBehavior beh in _tutorialItems) {
if(beh._popupName == behaviorName) {
return beh;
}
}
print ("Could not find behavior of name " + behaviorName);
return null;
}
And then returns it to function B, which then, ideally, would be able to change a property of the returned item:
public void SetTutorialItem(bool state, string itemName) {
TutorialPopupBehavior beh = GetBehavior(itemName);
if(beh == null) {
print ("No tutorial item found, so can't set it to " + state);
return;
}
//idealistic code: beh._isShown = true;
}
The _isShown property of that element would then be changed permanently in the original _tutorialItems array...how do you all accomplish this, or design differently, so as to avoid the problem? The reason I ask is because I have a number of arrays to search, and I don't want to complicate my code by asking the same class to search through the same set of arrays more than once.

public void GetBehavior(string behaviorName, ref TutorialPopupBehavior b) {
foreach(TutorialPopupBehavior beh in _tutorialItems) {
if(beh._popupName == behaviorName) {
b = beh;
Return;
}
}
print ("Could not find behavior of name " + behaviorName);
b = null;
}
Read this msdn article

Related

creating global string array through its own class, but still not recognized in different class method C#

Created a simple class with one element, a string [] array and filled it with elements. I want to be able to add and delete elements in this array anywhere in my application, but it is not accessable. been trying variations for two days so coming to the best for help.
enter code here
public static void TestSlots()
{
String currentBehavior = _core.GetVariable("$_current_name", false);
bool success1 = _core.ApiApp().SetDiagOutput("MYWARNING " + currentBehavior + " is");
int indexNumber = MedIntents.medIntents.IndexOf(currentBehavior);
;
if (indexNumber < 0)
{
return;
}
else
{
//Global.MedIntents.RemoveAt(indexNumber);
bool success = _core.ApiApp().SetDiagOutput("MYWARNING " + currentBehavior + " removed");
}
//now check if they asked or hit more than one important entity
return;
}
// Console.WriteLine("Hello World!");
}
internal class MedIntents
{
public string[] medIntents = new string[] {
"any_chills",
"constant_or_intermittent",
"gradual_or_sudden",
"had_them_before",
"how_often",
"howdoesitstart",
"hurt_elsewhere",
"nausea_or_vomitting",
"numbness",
"pain_relief",
"relation_to_food_or_medical",
"scaleofone2ten",
"warning_signs"
};
medIntents is an instance member. You may want to convert it to a static member. To prevent modification, you can add the readonly modifier. – Crafted Pod 2 hours ago

replacing a variable text with other text in c#

I am using c# and sitecore to basically use tokens in certain places ( see: how to create a custom token in sitecore ). I think I have a solution, but am not sure as to why it is not working, even though I am getting no errors.
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
var sValue = args.FieldValue.ToString();
foreach (Item child in tokenItem.Children)
{
if (child.Template.Name == "Token")
{
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (sValue.Contains(home))
{
home.Replace(home, hContent);
}
}
}
}
home and hContent pull up the correct values of each container, but when the page loads, it still has the "home" value inputted (the ie: ##sales) in the content area instead of the new value, which is stored in hContent. The sValue contains everything (tables, divs, text) and I was trying to single out a value that equals to "home" and replace the "home" value with hContent. What am I missing?
If your code is implemented as a processor for the RenderField pipeline, you need to put the result of your work back into args. Try something like this:
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
var sValue = args.Result.FirstPart;
foreach (Item child in tokenItem.Children){
if (child.Template.Name == "Token") {
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (sValue.Contains(home)) {
sValue = sValue.Replace(home, hContent);
}
}
}
args.Result.FirstPart = sValue;
}
Note that you need to be sure to patch this processor into the pipeline after the GetFieldValue processor. That processor is responsible for pulling the field value into args.Result.FirstPart.
You code isn't really doing anything. You seem to be replacing the tokens on the token item field itself (child.Fields["Title"] and child.Fields["Content"]), not on the output content stream.
Try the following, you need to set the args to the replaced value, replacing both the FirstPart and LastPart properties: Replace Tokens in Rich Text Fields Using the Sitecore ASP.NET CMS (link to the code in the "untested prototype" link).
I would refactor your code to make it easier:
public void Process(RenderFieldArgs args)
{
args.Result.FirstPart = this.Replace(args.Result.FirstPart);
args.Result.LastPart = this.Replace(args.Result.LastPart);
}
protected string Replace(string input)
{
Item tokenItem = Sitecore.Context.Database.Items["/sitecore/content/Site Content/Tokens"];
if (tokenItem.HasChildren)
{
foreach (Item child in tokenItem.Children)
{
if (child.Template.Name == "Token")
{
string home = child.Fields["Title"].Value;
string hContent = child.Fields["Content"].Value;
if (input.Contains(home))
{
return input.Replace(home, hContent);
}
}
}
}
return input;
}
This is still not optimal, but gets you closer.
Well, Do you know what happens when you performs home.Replace(home, hContent);, it will create a new instance by replacing the content of the come with what is in hContent so what you need to do is, assign this instance to a new variable or to home itself. hence the snippet will be like the following:
if (sValue.Contains(home))
{
home = home.Replace(home, hContent);
}
Have you tried:
home = home.Replace(home,hContent);

How do I reattach a deep-cloned element to a reference-tree?

Today I hit an issue while using a reference in C#. My use-case is the following: I have a global configuration-object in a winform-application. When opening the settings-screen, the settings-part of the object gets deep-cloned. At the time of clicking the save button, the element should get saved back to the original reference. This is not working as I first expected it to.
I have prepared a dotnet-fiddle for you to take a look at the problem. If someone is aware of a way to solve this problem, I am more than thankful for your input. I am thankful for pointing me to the correction too (I am sure someone has solved this issue in a much much cleaner way).
1) We have an globally avaiable static object structure
2) At a point in time, a part of this structure should be deattached from the object structure
3) The deattached part will be edited
4) At a later point in time, the part MAYBE should be reattached to the original reference in the object structure again
I am a frontend developer and its pretty hard to express my problem with words, so take a look at my code:
https://dotnetfiddle.net/qzJqC4
--- For readers from the far future where links are a thing of the past ---
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace DemoCloneAndReattach
{
[Serializable]
public class DogFamily
{
public DogFamily()
{
PrettyDogs = new List<PrettyDog>();
}
public List<PrettyDog> PrettyDogs { get; set; }
}
[Serializable]
public class PrettyDog
{
public string Name { get; set; }
public int NumberOfEars { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
// Note: The WriteLines will help you to validate the correctness of the solution. Thanks a lot!
// Setting up
DogFamily dogFamily = new DogFamily();
dogFamily.PrettyDogs.Add(new PrettyDog() { Name = "OriginalDog", NumberOfEars = 2 });
// Getting the dog with the name "OriginalDog"
PrettyDog originalDog = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
originalDog.NumberOfEars = 3;
Console.WriteLine("originalDog has NumberOfEars (expected 3): " + originalDog.NumberOfEars);
// Checking if the originalDog in the List has the value updated (from 2 to 3). It does.
PrettyDog checkDogOne = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
Console.WriteLine();
Console.WriteLine("checkDogOne has NumberOfEars (expected 3): " + checkDogOne.NumberOfEars);
// Now creating a deep-clone of the originalDog (this will result in a brand new object, not related to the DogFamily in any way)
PrettyDog clonedDog = DeepClone<PrettyDog>(originalDog);
// Doing something that should not YET be written to the DogFamily-reference tree.
clonedDog.NumberOfEars = 7;
// Checking if the clonedDog has not the same reference as the originalDog. As expected, it hasn't.
Console.WriteLine();
Console.WriteLine("clonedDog has NumberOfEars (expected 7): " + clonedDog.NumberOfEars);
Console.WriteLine("originalDog still has NumberOfEars (expected 3): " + originalDog.NumberOfEars);
// I want the behavior below, but automated (some kind of reverse-matching or -reattaching-logic to the reference of originalDog):
originalDog.Name = clonedDog.Name;
originalDog.NumberOfEars = clonedDog.NumberOfEars;
// Maybe the call to the solution would look like this:
// Reattach<PrettyDog>(originalDog, clonedDog);
Console.WriteLine();
Console.WriteLine("originalDog now has NumberOfEars (expected 7): " + originalDog.NumberOfEars);
Console.WriteLine("clonedDog has still NumberOfEars (expected 7): " + clonedDog.NumberOfEars);
// Checking if the reference is set correctly (not only the originalDog-reference but the whole reference-tree)
PrettyDog checkDogTwo = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
Console.WriteLine();
Console.WriteLine("checkDogTwo has NumberOfEars (expected 7 - this is the tricky one): " + checkDogTwo.NumberOfEars);
}
public static T DeepClone<T>(T obj)
{
if (obj == null) return default(T);
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
public static void Reattach<T>(T original, T clone)
{
// Logic for replacing the original with the clone without damaging the reference-tree
}
}
}

Recursive conditions

Sorry to put up yet another recursion question, but I've looked over a fair few on here and haven't found the solution for my problem.
I use the below function:
unsafe
{
// Allocate global memory space for the size of AccessibleContextInfo and store the address in acPtr
IntPtr acPtr = Marshal.AllocHGlobal(Marshal.SizeOf(new AccessibleContextInfo()));
try
{
Marshal.StructureToPtr(new AccessibleContextInfo(), acPtr, true);
if (WABAPI.getAccessibleContextInfo(vmID, ac, acPtr))
{
acInfo = (AccessibleContextInfo)Marshal.PtrToStructure(acPtr, typeof(AccessibleContextInfo));
if (!ReferenceEquals(acInfo, null))
{
AccessibleTextItemsInfo atInfo = new AccessibleTextItemsInfo();
if (acInfo.accessibleText)
{
IntPtr ati = Marshal.AllocHGlobal(Marshal.SizeOf(new AccessibleTextItemsInfo()));
WABAPI.getAccessibleTextItems(vmID, ac, ati, 0); //THIS IS WHERE WE DO IT
atInfo = (AccessibleTextItemsInfo)Marshal.PtrToStructure(ati, typeof(AccessibleTextItemsInfo));
if (ati != IntPtr.Zero)
{
Marshal.FreeHGlobal(ati);
}
}
AccessibleTreeItem newItem = BuildAccessibleTree(acInfo, atInfo, parentItem, acPtr);
newItem.setAccessibleText(atInfo);
if (!ReferenceEquals(newItem, null))
{
for (int i = 0; i < acInfo.childrenCount; i++)
{
//Used roles = text, page tab, push button
if (acInfo.role_en_US != "unknown" && acInfo.states_en_US.Contains("visible")) // Note the optomization here, I found this get me to an acceptable speed
{
AccessibleContextInfo childAc = new AccessibleContextInfo();
IntPtr childContext = WABAPI.getAccessibleChildFromContext(vmID, ac, i);
GetAccessibleContextInfo(vmID, childContext, out childAc, newItem);
if (childContext != IntPtr.Zero)
{
Settings.Save.debugLog("Releasing object " + childContext.ToString() + " from JVM: " + vmID);
WABAPI.releaseJavaObject(vmID, childContext);
childContext = IntPtr.Zero;
}
}
}
}
return newItem;
}
}
else
{
acInfo = new AccessibleContextInfo();
}
}
finally
{
if (acPtr != IntPtr.Zero)
Marshal.FreeHGlobal(acPtr);
}
}
return null;
}
To build an AccessibleTreeItem representing the entire GUI of a Java application. However, this function takes 5-6 seconds to run. I'm only looking for one particular subsection of the tree (Lets call it Porkchops).
What I'd like to do is prior to building the tree, get the values and as soon as acRole.name == "Porkchop", use that as the parent object and create an AccessibleTreeItem that represents the subtree.
How on earth do I manage this? If this is a simple question, apologies, but it's driving me crazy.
Edit 1 - The performance hit is encountered on releaseJavaObject(), as when I remove that line the function completes in less than a second, but it creates a horrible memory leak.
Therefore, I'm not really looking for alternative solutions, as I know that the above does work correctly. I just need some way to check the value of acInfo.name prior to creating the tree, and then using the correct acInfo node as the parent.
Edit 2 - See the attached image for a better explanation than my rambling. Currently, the function will pull this entire tree from the JVM. I've highlighted the appropriate section that I work with, and would like to know if there's a way that will allow me to get that information, without building the entire tree. Or even if I could just return the tree once all children of that node have been populated.

Get-methods or private property?

This is just a matter of taste but I'd like to hear some of your opinions (that's also why this question is marked as subjective).
If I have a property, say
private string _Text;
public string Text;
get
{
object tmp = ViewState["Text"];
if (tmp != null)
_Text = Convert.ToString(tmp);
return _Text;
}
set
{
ViewState.Add("Text", value);
}
Now this is the property which may be specified by the programmer, by setting some custom text. This is then mapped - say - to some control on the UI. In the default case however, the Text of the control comes from a predefined resource file. So internally to handle that internally in a better way, I'd have some central point where I check whether the user has specified the "Text" property (above) and if so, use that data, otherwise rely on the default one from the resource file.
So what approach would you take? I have two options in mind:
private string ResolvedText
{
get
{
if(!string.IsNullOrEmpty(Text))
return Text;
else
//return the one from the resource file
}
}
Or put everything in a method
public string GetResolvedText()
{
if(!string.IsNullOrEmpty(Text))
return Text;
else
//return the one from the resource file
}
The question may sound stupid to you since it's really a minor difference. But I'd like to know whether there are some conventions about this.
Thx
Personally, I'd take the body of your GetResolvedText method, and use it in the property, thus:
private string _Text;
public string Text
{
get
{
if(string.IsNullOrEmpty(_Text))
//return the one from the resource file
else
return _Text;
}
set
{
_Text = value;
}
}
This puts all the responsibility for managing the string into the one place. The class itself can access _Text internally, if it needs the raw value.
I find that the best general rule here is: if calling the action twice results in multiple resource calls or different behaviour - use a method.
So, in your example use of a property is fine if it caches:
public string ResolvedText
{
get { return Text ?? (Text = GetResolvedText()); }
}
However the method doesn't need to - users expect it to be a more intensive operation:
public string GetResolvedText()
{
//return the one from the resource file
}
The design question is how do you want this class to be used?
A property will get called as if it is a 'cheap' operation:
if( myInstance.ResolvedText != null &&
myInstance.ResolvedText.Length > 5 )
Response.Write( myInstance.ResolvedText );
A method hints to the developer that they should call it as few times as possible:
string resolvedText = myInstance.GetResolvedText();
if( resolvedText != null &&
resolvedText.Length > 5 )
Response.Write( resolvedText );
Personally I prefer to keep interim classes simple, so in the vast majority of cases I would use the method model.
As this is a fairly standard convention you should avoid properties that don't cache and methods that do.
I would keep this as a property, since it represents a single value that does not require a lot of computing to retrieve.
To me, if the getter can't throw an exception, or null/invalid value, it should be a property. It is what properties are made for.
BUT, if you do some complicated stuff, if has to be a a function getter. Obviously here you have only 1 if, so I would use a property.
Reworking together your example and Steve's answer, plus adding in some caching, as obviously the resource value should be read only once since it never changes and by contract we must return the value from the property as fast as possible:
private static string ResourceText;
static [constructor]
{
ResourceText = //get resource;
}
private string text;
public string Text;
get
{
string tmp = (string)ViewState["Text"];
if (!String.IsNullOrEmpty(tmp))
text = tmp;
else
text = ResourceText;
return text;
}
set
{
ViewState.Add("Text", value);
// Note: passing null or empty strings will not work.
}

Categories

Resources