Pass class object by reference to method override - c#

I've been attempting to write a section of code for this project so that it can print out whichever BasePlayer object's hand along with the total as such (: (card) (card) (total) - (playerName)) and I've been trying to override ToString() to be able to accomplish this. Issue is I need to pass the referenced object's specific hand but can't figure out how to pass by reference while using an override. I'm not sure if it's syntax or how I'm doing it, I would just like to fix it.
The issue is the bottom most function:
using System;
using System.Collections.Generic;
using System.Text;
using Blackjack_C;
namespace Blackjack_C
{
public class BasePlayer : Hand
{
public string name;
private (ref BasePlayer ap);
public BasePlayer(ref string name)
{
this.name = name;
}
Hand hand = new Hand();
public bool IsBusted()
{
return hand.getTotal() > 21;
}
public void Bust()
{
Console.Write(name + " busts.");
}
public override string ToString(ref BasePlayer ap)
{
string output = ":\t";
if (!(ap.m_Cards.Count == 0))
{
foreach (var c in ap.m_Cards)
{
output += (c + "\t");
}
if (ap.getTotal() != 0)
{
output += ("(" + ap.getTotal() + ")");
}
return output;
}
else
{
return("<empty>");
}
}
}
}
Here is the definition of the Hand class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Blackjack_C;
namespace Blackjack_C
{
public class Hand
{
protected List<Card> m_Cards;
~Hand()
{
clearHand();
}
public void add(Card pCard)
{
m_Cards.Insert(m_Cards.Count, pCard);
}
public void clearHand()
{
m_Cards.Clear();
}
public int getTotal()
{
// If the hand is empty it cannot get total
if (m_Cards.Count == 0)
{
return 0;
}
// Gets total value of deck (doesn't run if Dealer's hand)
int total = 0;
foreach (var c in m_Cards)
{
total += c.getValue();
}
// Bool to check if the hand has an Ace in it (doesn't run if Dealer's hand)
bool containsAce = false;
foreach (var c in m_Cards)
{
if (c.getValue() == (int) Card.card_face.Ace)
{
containsAce = true;
}
}
// Checks if hand is dealer's hand and get's value whilst keeping it secret from the player
if (m_Cards.First().getValue() == 0)
{
//int total = 0;
foreach (var c in m_Cards)
{
total += c.getDealerValue();
}
//bool containsAce = false;
foreach (var c in m_Cards)
{
if (c.getDealerValue() == (int) Card.card_face.Ace)
{
containsAce = true;
}
}
}
// Checks if total is less than 11 to see if changing Ace to = 11 instead of = 1 is necessary
if (containsAce && total <= 11)
{
total += 10;
}
return total;
}
public Card getCard(int index)
{
if (index >= m_Cards.Count || index < 0)
return m_Cards[0];
else
{
return m_Cards[index];
}
}
}
}
Sorry for lack of a good post, this is my first time posting a question here.

i created the hand object with assumptions. Hand can have 2 or more card.
so you can try like this :
public class BasePlayer
{
public Hand Hand { get; set; }
public string Name { get; set; }
public BasePlayer(ref string name)
{
Name = name;
}
public bool IsBusted()
{
return Hand.GetTotal() > 21;
}
public void Bust()
{
Console.Write(Name + " busts.");
}
public override string ToString()
{
// you can access referenced string and specific hand on here
return string.Join(' ',Hand.Cards.Select(card=>$"{(card)}")) + $" {(Hand.GetTotal()) } "+ Name;
}
}
public class Hand
{
public List<int> Cards { get; set; }
public int GetTotal()
{
return Cards.Sum();
}
}

Related

Why is my C# Array changing without anything being assigned to it?

I have a small winforms program for a task which is to create a Recipe book. The application has two windows, but my bug pertains to only one.
I have two main classes: Recipe.cs and RecipeManager.cs, the idea is that the RecipeManager holds an array of Recipes. (For this task we weren't allowed to use Linq or ArrayLists)
Now, when I fill in the form and click "Add Recipe", the first one works successfully and the listBox populates correctly, however the second time I "Add Recipe" the recipeList array seems to get rewritten with the new Recipe entirely, and I have no idea why this is happening. The recipeList seems to change before my Add method even adds it to the array!
See gif of problem in question:
https://i.imgur.com/sIMICcG.gifv
Recipe.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace programmingTask4
{
public class Recipe
{
private string[] ingredientArray;
private string name;
private FoodCategory category;
private string description;
private const int maxNumOfIngredients = 20;
public string Name
{
get { return name; }
set { name = value; }
}
public FoodCategory Category
{
get { return category; }
set { category = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public string[] Ingredient
{
get { return ingredientArray; }
set { ingredientArray = value; }
}
public int MaxNumOfIngredients
{
get { return ingredientArray.Length; }
}
public Recipe(int maxNumOfIngredients)
{
Console.WriteLine("Recipe constructor was called!");
ingredientArray = new string[maxNumOfIngredients];
DefaultValues();
}
public void DefaultValues()
{
for (int i = 0; i < ingredientArray.Length; i++)
{
ingredientArray[i] = string.Empty;
name = string.Empty;
category = FoodCategory.Vegetarian;
description = string.Empty;
}
}
public int FindVacantPosition()
{
int results;
for (int i = 0; i < ingredientArray.Length; i++)
{
if(ingredientArray[i] == string.Empty)
{
results = i;
return results;
}
}
return -1;
}
public bool AddIngredient(string value)
{
bool ok;
int next = FindVacantPosition();
if(next >= 0)
{
ok = true;
ingredientArray[next] = value;
}
else {
ok = false ;
}
return ok;
}
public bool CheckIndex(int index)
{
bool check = false;
if(index <= ingredientArray.Length && index >= 0)
{
check = true;
}
return check;
}
public int GetCurrentNumOfIngredients()
{
int count = 0;
for (int i = 0; i < ingredientArray.Length; i++)
{
if (!string.IsNullOrEmpty(ingredientArray[i]))
{
count++;
}
}
return count;
}
public override string ToString()
{
int chars = Math.Min(description.Length, 15);
string descriptionText = description.Substring(0, chars);
if (string.IsNullOrEmpty(descriptionText))
descriptionText = "NO DESCRIPTION";
string textOut = string.Format("{0, -20} {1,4} {2,-12} {3,-15}", name, GetCurrentNumOfIngredients(), category.ToString(), descriptionText);
return textOut;
}
public bool ChangeIngredientAt(int index, string value)
{
bool bok = true;
if (CheckIndex(index))
ingredientArray[index] = value;
else
bok = false;
return bok;
}
public bool DeleteIngredientAt(int index)
{
bool bok = true;
if (CheckIndex(index))
ingredientArray[index] = "NO DESCRIPTION";
else
bok = false;
return bok;
}
}
}
RecipeManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace programmingTask1
{
class RecipeManager
{
private Recipe[] recipeList;
public RecipeManager(int maxNumOfElements)
{
Console.WriteLine("Recipe manager constructor called!");
recipeList = new Recipe[maxNumOfElements];
}
private int FindVacantPosition()
{
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] == null)
{
Console.WriteLine("Found free position at: " + i);
return i;
}
}
return -1;
}
public bool CheckIndex(int index)
{
bool check = false;
if (index <= recipeList.Length && index >= 0)
{
check = true;
}
return check;
}
public Recipe GetRecipeAt(int index)
{
if (CheckIndex(index))
return recipeList[index];
else
return null;
}
public bool Add(Recipe newRecipe)
{
if (newRecipe == null)
return false;
bool ok;
int next = FindVacantPosition();
if (next >= 0)
{
ok = true;
Console.WriteLine("Setting recipe list at index " + next + " to " + newRecipe.ToString());
recipeList[next] = newRecipe;
}
else
{
Console.WriteLine("No space for recipe available! " + next);
ok = false;
}
return ok;
}
public int CurrentNumberofItems()
{
int num = 0;
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] != null)
{
num++;
}
}
return num;
}
public string[] RecipeListToString()
{
string[] results = new string[recipeList.Length];
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] != null)
results[i] = recipeList[i].ToString();
else
results[i] = string.Empty;
}
return results;
}
}
}
FormMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace programmingTask4
{
public partial class FormMain : Form
{
const int maxRecipe = 3;
const int maxIngredients = 20;
Recipe currRecipe = new Recipe(maxIngredients);
RecipeManager recipemanager = new RecipeManager(maxRecipe);
public FormMain()
{
Console.WriteLine("Form constructor was called!");
InitializeComponent();
InitializeGui();
}
public void InitializeGui()
{
comboBoxCategory.DataSource = Enum.GetValues(typeof(FoodCategory));
}
public void UpdateGUI()
{
//listBoxDisplay.Text = recipemanager.CurrentNumberofItems().ToString();
//listBoxDisplay.Text = currRecipe.Ingredient.ToString();
string[] recipeListStrings = recipemanager.RecipeListToString();
listBoxDisplay.Items.Clear();
listBoxDisplay.Items.AddRange(recipeListStrings);
}
private void buttonRecipe_Click(object sender, EventArgs e)//add recipe button
{
currRecipe.Category = (FoodCategory)comboBoxCategory.SelectedIndex;
currRecipe.Name = textBoxRecipeName.Text.Trim();
currRecipe.Description = richTextBoxDescription.Text.Trim();
Console.WriteLine("Adding recipe: " + currRecipe.ToString());
bool result = recipemanager.Add(currRecipe);
Console.WriteLine("Result was " + result + " for adding to recipe list");
UpdateGUI();
currRecipe.DefaultValues();
}
}
}
Recipe is a class, which mean it's a reference type.
In your main form, your currRecipe instance is never changed.
RecipeManager has an array to store references of instance but unfortunately it stores the same instance because of 2.
Since RecipeManager stores the same instance of currRecipe, any modification on currRecipe would display N times.
To prevent it. Modify your buttonRecipe_Click
private void buttonRecipe_Click(object sender, EventArgs e)//add recipe button
{
currRecipt = new Recipe(maxIngredients);
currRecipe.Category = (FoodCategory)comboBoxCategory.SelectedIndex;
currRecipe.Name = textBoxRecipeName.Text.Trim();
currRecipe.Description = richTextBoxDescription.Text.Trim();
Console.WriteLine("Adding recipe: " + currRecipe.ToString());
bool result = recipemanager.Add(currRecipe);
Console.WriteLine("Result was " + result + " for adding to recipe list");
UpdateGUI();
// No need to reset it, use new one everytime.
//currRecipe.DefaultValues();
}

StackOverflowException: The requested operation caused a stack overflow

I've made some code in Unity2d with c# and interface.
LevelingSystem.cs is putted in empty gameobject.
And i getting error:
StackOverflowException: The requested operation caused a stack overflow.
PlayerCap.get_actExp () (at Assets/Scripts/player/PlayerCap.cs:17)
PlayerCap.get<message truncated>
CapLevel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
interface ICapLevel
{
float multiplierA { get; set; }
float multiplierB { get; set; }
float multiplierC { get; set; }
float multiplierD { get; set; }
int lvlCap { get; set; }
List<double> expCap { get; set; }
float actExp { get; set; }
void GenerateExpPerLvl();
float RequiredExp(int level);
}
PlayerCap.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCap : ICapLevel
{
public float multiplierA { get { return multiplierA; } set { multiplierA = 280f; } }
public float multiplierB { get { return multiplierB; } set { multiplierB = 100f; } }
public float multiplierC { get { return multiplierC; } set { multiplierA = 1.15f; } }
public float multiplierD { get { return multiplierD; } set { multiplierD = 2.3f; } }
public int lvlCap { get { return lvlCap; } set { lvlCap = 210; } }
public List<double> expCap { get { return expCap; } set { expCap = new List<double>(); } }
public float actExp { get { return actExp; } set { actExp = 0f; } }
public void GenerateExpPerLvl()
{
Debug.Log("implementation successful");
for (int expLevel = 1; expLevel <= lvlCap; expLevel++)
{
expCap.Add(RequiredExp(expLevel - 1));
}
}
public float RequiredExp(int level)
{
double formulaRounded;
var formula = multiplierB * (Mathf.Pow(multiplierC, level - 1)) + multiplierA * (Mathf.Pow(level, multiplierD));
if (formula < 1000)
{
if ((formula % 10) == 0)
{
formulaRounded = formula;
return (float)formulaRounded;
}
else
{
formulaRounded = Math.Round((formula / 1000), 1, MidpointRounding.AwayFromZero);
}
}
else
{
formulaRounded = Math.Round((formula / 1000), 0, MidpointRounding.AwayFromZero);
}
return (float)formulaRounded * 1000;
}
}
LevelingSystem.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelingSystem : MonoBehaviour
{
//interface implementation
private PlayerCap _pCap;
private ICapLevel _ICap;
private List<double> _pExpCap;
private int pLvl;
private float _pActExp;
public void Awake()
{
_pCap = new PlayerCap();
_ICap = _pCap;
}
private void Start()
{
_pActExp = _ICap.actExp;
_ICap.GenerateExpPerLvl();
_pExpCap = _ICap.expCap;
}
public void AddExp(float amount)
{
_pActExp += amount;
StartCoroutine(CapLevelCheck(amount));
}
private IEnumerator CapLevelCheck(float amount)
{
while (true)
{
if (_pActExp >= _pExpCap[pLvl])
{
_pActExp -= (float)_pExpCap[pLvl];
AddLevel(1);
} else
{
Debug.Log("You Get " + amount + " Experience and you have " + pLvl + " Lvl. *Click noice!");
break; //otherwise loop will do in infinite
}
yield return 0;
}
}
public void AddLevel(int amount)
{
pLvl += amount;
}
public int GetActualLevel()
{
return pLvl;
}
}
Im try few things like get rid off for in method GenerateExpPerLvl() and error gones away so my suspicious thing is list variable but maybe im wrong.
Thanks for help :)
The problem is here:
public float actExp { get { return actExp; } set { actExp = 0f; } }
// ^ Problem here & ^ same problem here
You are calling your Property inside its own getter and setter. It creates an infinite loop... (everytime you call actExp it will call itself)
Instead you should just write (if there is no logic inside accessors):
public float actExp { get; set; }

My property only has a get, but I want that value to change everytime I call it

I am struggling with the this for a few hours now. I only want to use a get in my property. When I call a function, it gets a number from that property(10) and should substract 1 from the 10, which makes 9. But I have no idea how to save this 9, and do it minus 1 everytime, so the next time I call it, it becomes 8. I Hope this is clear enough.
main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
do
{
Zwakmonster zwakmonster = new Zwakmonster();
Sterkmonster sterkmonster = new Sterkmonster();
List<IMonster> monster = new List<IMonster>();
string lijn;
string test = "exit";
string nieuwelijn;
string zwak = "zwakmonster";
string sterk = "sterkmonster";
string groen = "groen";
string geel = "geel";
Sterkmonster henk = new Sterkmonster();
henk.Naam = sterk;
henk.Kleur = groen;
Zwakmonster piet = new Zwakmonster();
piet.Kleur = geel;
piet.Naam = zwak;
Console.WriteLine("Schrijf zwakmonster_iemand of sterkmonster_iemand");
lijn = Console.ReadLine();
if (lijn == test)
{
Environment.Exit(0);
}
else if (lijn.StartsWith("hit"))
{
if (lijn.StartsWith("hit "))
{
nieuwelijn = lijn.Remove(0, 4);
if (nieuwelijn == sterk)
{
henk.Hit();
Console.WriteLine(sterkmonster);
}
else if (nieuwelijn == zwak)
{
piet.Hit();
Console.WriteLine(zwakmonster);
}
else
{
Console.WriteLine("iets ging er fout");
}
}
else
{
Console.WriteLine("Ben je misschien een spatie vergeten na ''hit''?\n");
}
}
else
{
Console.WriteLine("Verkeerd commando ingevoerd\n");
}
} while (1 == 1);
}
}
}
IMonster.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
interface IMonster
{
string Naam
{
get;
set;
}
string Kleur
{
get;
set;
}
int Levens
{
get;
}
void Hit();
}
}
zwakmonster.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Zwakmonster : IMonster
{
private string mijnNaam;
private string mijnKleur;
private int mijnLevens = 10;
private int nieuwelevens;
public string Naam
{
get { return mijnNaam; }
set { mijnNaam = value; }
}
public string Kleur
{
get { return mijnKleur; }
set { mijnKleur = value; }
}
public int Levens
{
get { return mijnLevens; }
}
public void Hit()
{
mijnLevens = mijnLevens - 1;
nieuwelevens = mijnLevens;
Console.WriteLine(nieuwelevens);
}
}
}
Change this
public void Hit()
{
newlife = mijnLevens - 1;
}
to this
public void Hit()
{
mijnLevens = mijnLevens - 1;
newlife = mijnLevens;
}
this will make sure mijnLevens is decremented. Currently, mijnLevens is always 10.
Change this:
do
{
Zwakmonster zwakmonster = new Zwakmonster();
To this
Zwakmonster zwakmonster = new Zwakmonster();
do
{
So that you don't create a new object for every iteration.
Allan Elder already gave the right answer, to make things less complicated i would use only one var for your lives count
class Zwakmonster : IMonster
{
private string mijnNaam;
private string mijnKleur;
private int lives = 10;
public string Naam
{
get { return mijnNaam; }
set { mijnNaam = value; }
}
public string Kleur
{
get { return mijnKleur; }
set { mijnKleur = value; }
}
public int Levens
{
get { return lives; }
}
public void Hit()
{
lives = lives - 1;
}
}
mijnLevens will always have the value 10.
You need to assign the reduced value back to mijnLevens

Calculate the sum of the objects in ListNode

How I can make a method to calculate the sum of listOfNodes objects? I was doing with foreach statement like
foreach(int s in listOfNodes)
sum += s;
to get all the nodes but it didn't worked.
It says:
Error 1 foreach statement cannot operate on variables of type 'ConsoleApplication1.Program.List' because 'ConsoleApplication1.Program.List' does not contain a public definition for 'GetEnumerator' C:\Users\TBM\Desktop\I\ConsoleApplication1\ConsoleApplication1\Program.cs 24 13 ConsoleApplication1
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List listOfNodes = new List();
Random r = new Random();
int sum = 0;
for (int i = 0; i < 10; i++)
{
listOfNodes.addObjects(r.Next(1, 100));
}
listOfNodes.DisplayList();
Console.ReadLine();
}
class ListNode
{
public object inData { get; private set; }
public ListNode Next { get; set; }
public ListNode(object dataValues)
: this(dataValues, null) { }
public ListNode(object dataValues,
ListNode nextNode)
{
inData = dataValues; Next = nextNode;
}
} // end class ListNode
public class List
{
private ListNode firstNode, lastNode;
private string name;
public List(string nameOfList)
{
name = nameOfList;
firstNode = lastNode = null;
}
public List()//carieli list konstruktori saxelis "listOfNodes"
: this("listOfNodes") { }
public void addObjects(object inItem)
{
if (isEmpty())
{ firstNode = lastNode = new ListNode(inItem); }
else { firstNode = new ListNode(inItem, firstNode); }
}
private bool isEmpty()
{
return firstNode == null;
}
public void DisplayList()
{
if (isEmpty())
{ Console.Write("Empty " + name); }
else
{
Console.Write("The " + name + " is:\n");
ListNode current = firstNode;
while (current != null)
{
Console.Write(current.inData + " ");
current = current.Next;
}
Console.WriteLine("\n");
}
}
}//end of class List
}
}
As the error message says, you need to implement GetEnumerator in order to foreach over something. So, implement GetEnumerator:
public IEnumerator GetEnumerator()
{
ListNode node = firstNode;
while (node != null)
{
yield return node;
node = node.Next;
}
}
You can now have your List class implement the IEnumerable interface too, if you want.
The alternative would be to not use a foreach loop, and instead use a while loop, as I did here, or you did in your DisplayList method.

Query an object but miss out field/Property (Soda)

I'm trying stuff with db4o since a few days but I got a problem.
Imagine this class just for test:
class Test
{
public string TestString
public int Number;
public Bitmap Bm;
public Test2 T2;
}
I'm saving the entire class and all sub-objects.
But when I load it, I don't want Bm to be loaded (just leave it null). How can I leave it out?
I need to save it because in some cases, I need to load it.
It's a performance thing because the pictures are really large.
Well, the easiest solution (IMHO) is to wrap the BitMap class in another class and use db4o's transparent activation feature:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Activation;
using Db4objects.Db4o.TA;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { Name = "c1", Huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
config.Common.Add(new TransparentActivationSupport());
config.Common.ActivationDepth = 0;
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("{0}", db.Ext().IsActive(item));
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.huge), item.huge);
Console.WriteLine("[Huge] {0} : {1}", db.Ext().IsActive(item.Huge), item.Huge);
}
}
}
class C1 : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass Huge
{
get
{
Activate(ActivationPurpose.Read);
return huge;
}
set
{
Activate(ActivationPurpose.Write);
huge = value;
}
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
public MyHugeClass huge;
private string name;
[NonSerialized]
private IActivator activator;
}
class MyHugeClass : IActivatable
{
public string Name
{
get
{
Activate(ActivationPurpose.Read);
return name;
}
set
{
Activate(ActivationPurpose.Write);
name = value;
}
}
public MyHugeClass(string name)
{
this.name = name;
}
public override string ToString()
{
Activate(ActivationPurpose.Read);
return string.Format("[{0}] {1}", GetType().Name, name);
}
public void Bind(IActivator activator)
{
if (this.activator != null && activator != null)
{
throw new Exception("activation already set");
}
this.activator = activator;
}
public void Activate(ActivationPurpose purpose)
{
if (activator != null)
{
activator.Activate(purpose);
}
}
private string name;
[NonSerialized]
private IActivator activator;
}
}
Note that even though I have implemented the IActivatable interface manually I don't recommend that; you can use db4otool to implement it for you automatically.
Another possible solution is to control activation for your type (when an object is not activated in db4o, its reference is valid but all of its fields will be not initialized taking no space whatsoever).
For instance you can do something like:
using System;
using System.IO;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Events;
namespace ActivationDepth
{
class Program
{
static void Main(string[] args)
{
var dbFilePath = Path.GetTempFileName();
using (var db = Db4oEmbedded.OpenFile(dbFilePath))
{
db.Store(new C1 { name = "c1", c2 = new C2("c2"), huge = new MyHugeClass("I am really huge....")});
}
var config = Db4oEmbedded.NewConfiguration();
using (var db = Db4oEmbedded.OpenFile(config, dbFilePath))
{
var activate = false;
var fac = EventRegistryFactory.ForObjectContainer(db);
fac.Activating += (sender, eventArgs) =>
{
if (!activate && eventArgs.Object.GetType() == typeof(MyHugeClass))
{
Console.WriteLine("[{0}] Ignoring activation.", eventArgs.Object);
eventArgs.Cancel();
}
else
{
Console.WriteLine("[{0}] Activation will proceed.", eventArgs.Object);
}
};
var item = db.Query<C1>().ElementAt(0);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
activate = true;
db.Activate(item.huge, 3);
Console.WriteLine("[IsActive] {0}", db.Ext().IsActive(item.huge));
}
}
}
class C1
{
public string name;
public C2 c2;
public MyHugeClass huge;
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class C2
{
public string name;
public C2(string name)
{
this.name = name;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, name);
}
}
class MyHugeClass
{
public string text;
public MyHugeClass(string text)
{
this.text = text;
}
public override string ToString()
{
return string.Format("[{0}] {1}", GetType().Name, text);
}
}
}
You can also play with activation depth.
Hope this help.

Categories

Resources