I have this strange problem in my unit tests. See the following code
_pos = null;
Utilities.InitPOS(_pos, trans);
Assert.IsNotNull(_pos); //fails
The InitPOS functions looks like
public static void InitPOS(POSImplementation pos, Transaction newTransaction)
{
pos = new POSImplementation();
pos.SomeProp = new SomeProp();
pos.SomeProp.SetTransaction(newTransaction);
Assert.IsNotNull(pos);
Assert.IsNotNull(pos.SomeProp);
}
The object POSImplementation is an implementation of some interface and it is a class, so it is a reference type...
Any idea?
You're passing a reference to an object to InitPOS (namely a null reference), not a reference to the variable named _pos. The effect is that the new POSImplementation instance is assigned to the local variable pos in the InitPOS method, but the _pos variable remains unchanged.
Change your code to
_pos = Utilities.InitPOS(trans);
Assert.IsNotNull(_pos);
where
public static POSImplementation InitPOS(Transaction newTransaction)
{
POSImplementation pos = new POSImplementation();
// ...
return pos;
}
pos = new POSImplementation();
Just what are you doing there, if someone is passing pos into the method already? Are you missing a ref attribute on that parameter maybe?
You don't pass the instance by reference,
you pass the reference by value.
Related
I have the following code
Driver Code
var provider = DataManager.BuildDatabase<FileDatabase>(config,false,dbPath).Result;
DataManager.cs
public static async Task<IStorageProvider> BuildDatabase<TStorageProvider>(DbConfig config,
bool isBuildUniqueAddress = false,params object[] buildParam) where TStorageProvider : IStorageProvider
{
var t = typeof(TStorageProvider);
//merging params
var buildConfig= new DbData(config);
buildParam= buildParam.ToList().Prepend(buildConfig).ToArray();
Console.WriteLine($"Building Database of type:{t.FullName}");
IStorageProvider? storageProvider = (IStorageProvider?)Activator.CreateInstance(t,buildParam);
}
and Here is my Constructor for type FileDatabase
FileDatabase.cs
public FileDatabase(DbConfig config,string dbPath)
{
_dbData = new DbData(config);
DbPath=dbPath;
if (!File.Exists(dbPath))
{
Flush().RunSynchronously();
}
}
When I try to execute code above, it gives me:
MissingMethodException: Constructor on type 'assertUpdaterRefactor.StorageProvider.FileDatabase' not found.\
I tried to debug content of variable buildParam
.
The debugger shows the buildParam is an object array and exactly matches the constructor. I just can't figure out the reason causing this problem. Please help
UPDATE:
When I tried to create a new object array. The issue fixed magically
IStorageProvider? storageProvider = (IStorageProvider?)Activator.CreateInstance(t, new object[]{config,"someStringValue"});
Here is the original code copied from above just for reference
IStorageProvider? storageProvider = (IStorageProvider?)Activator.CreateInstance(t,buildParam);
I want to know the causes and why the original code does not work.
The first argument of the FileDatabase is DbConfig, in your BuildDatabase you use a type DbData.
So instead of passing an instance of var buildConfig= new DbData(config); pass the config directly.
Would be something like:
public static async Task<IStorageProvider> BuildDatabase<TStorageProvider>(DbConfig config,
bool isBuildUniqueAddress = false,params object[] buildParam) where TStorageProvider : IStorageProvider
{
var t = typeof(TStorageProvider);
//merging params
buildParam= buildParam.ToList().Prepend(config).ToArray();
Console.WriteLine($"Building Database of type:{t.FullName}");
IStorageProvider? storageProvider = (IStorageProvider?)Activator.CreateInstance(t,buildParam);
}
I want to make a deep Copy for my Class TreeNode. Here is my code:
public TreeNode(TreeNode node, GUIStyle inPointStyle, GUIStyle outPointStyle, Action<ConnectionPoint> OnClickInPoint, Action<ConnectionPoint> OnClickOutPoint)
{
this.rect = new Rect(node.rect);
this.style = new GUIStyle(node.style);
this.inPoint = new ConnectionPoint(this, ConnectionPointType.In, inPointStyle, OnClickInPoint);
this.outPoint = new ConnectionPoint(this, ConnectionPointType.Out, outPointStyle, OnClickOutPoint);
this.defaultNodeStyle = new GUIStyle(node.defaultNodeStyle);
this.selectedNodeStyle = new GUIStyle(node.selectedNodeStyle);
this.allDecorations = new List<GameObject>(node.allDecorations);
this.objs = new Dictionary<GameObject, IndividualSettings>(node.objs);
this.name = String.Copy(node.name);
this.RemoveClonedObj = new Action(node.RemoveClonedObj);
this.OnChangeView = new Action<TreeNode>(node.OnChangeView);
this.OnRemoveNode = new Action<TreeNode>(node.OnRemoveNode);
this.OnCopyNode = new Action<TreeNode>(node.OnCopyNode);
this.PreviewTree = new Action<TreeNode, bool> (node.PreviewTree);
}
However, the Rider gave me the warning:
It seems the Rider was saying that my "new" is meaningless.
If I follow Rider's instruction, usethis.RemoveClonedObj = node.RemoveClonedObj; what will happen for my copyed TreeNode's Actions aftering removing the orginal TreeNode? Will they be removed as well? If so, why does Rider give me such warning?
In C# 2.0 or above, the following codes are equivalent (DelegateType is a delegate type, as its name suggests):
newDelegate = new DelegateType(oldDelegate);
newDelegate = oldDelegate;
(See MSDN - How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide))
Also, Microsoft specifies (see here) that such operation will always create a new instance of DelegateType, which has the same invocation list as the oldDelegate. They do not refer to the same object (don't be confused by the = assignment):
The binding-time processing of a delegate_creation_expression of the form new D(E), where D is a delegate_type and E is an expression, consists of the following steps:
If E is a method group, the delegate creation expression is processed in the same way as a method group conversion (Method group conversions) from E to D.
If E is an anonymous function, the delegate creation expression is processed in the same way as an anonymous function conversion (Anonymous function conversions) from E to D.
If E is a value, E must be compatible (Delegate declarations) with D, and the result is a reference to a newly created delegate of type D that refers to the same invocation list as E. If E is not compatible with D, a compile-time error occurs.
So regarding your question
What will happen for my copyed TreeNode's Actions aftering removing the orginal TreeNode? Will they be removed as well?
Nothing will happen to them. They will not be removed.
By the way, since you are trying to make a deep copy of your tree-node, I suspect whether it is the correct way. Though you have created a new instance of your delegate, the class instance associated with it (the instance on which member methods will be invoked) stays the same.
Do not link instance methods to each other. This will lead to memory leaks.
Even after the original node is removed and no longer needed by your code, due to the reference from the copy the original instance will live in the memory and not be garbage collected.
I suspect this is not what you want, Test code for this
class Program
{
static void Main(string[] args)
{
First t = new First();
Second s = new Second();
t.Print = s.TestMethod;
s.test = "change";
s = null;
t.Print("Hell"); // can debug and see that the function call goes through and string test is = "change"
}
}
public class First
{
public string s;
public Action<string> Print;
}
public class Second
{
public string test = "created";
public void TestMethod (string test)
{
var res = "hello" + test + test;
}
}
Either your methods on the node should be part of the Node object, this way you do not have to assign them to new nodes, or they should be in a separate class, preferably static, so that creation of new nodes does not lead to a memory issue.
I have written the following function to create an axWindowsMediaPlayer playlist:
WMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
private void CreatePlaylist(string _currentId)
{
string selectedElementPageTypeValue = MainContentAreaBl.GetSelectedElementPageTypeValue(_currentId);
var selectedElementJumpToValue = MainContentAreaBl.GetSelectedElementValue(_currentId, "jumpTo");
if (selectedElementJumpToValue != null)
{
_currentId = selectedElementJumpToValue;
if (_currentId != null && _currentId != "menu" && selectedElementPageTypeValue == "video")
{
var playerFile = Path.Combine(Common.ContentFolderPath, MainContentAreaBl.GetSelectedElementDataPathValue(_currentId));
p2.appendItem(axWindowsMediaPlayer.newMedia(playerFile));
axWindowsMediaPlayer.currentPlaylist = p2;
CreatePlaylist(_currentId);
}
axWindowsMediaPlayer.Ctlcontrols.play();
}
}
Here var p2 is declared at class level. When I compiled my application, i received the following error message:
The contextual keyword 'var' may only appear within a local variable declaration
However, I cannot put var p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1"); inside the recursive function as it will create new playlist on each iteration.
How do I access p2 in my function?
Edit 1: I am seeing this in Output Window
COM Reference 'WMPLib' is the interop assembly for ActiveX control 'AxWMPLib' but was marked to be linked by the compiler with the /link flag. This COM reference will be treated as a reference and will not be linked.
Also, now it shows the following error on axWindowsMediaplayer:
A field initializer cannot reference the non-static field, method or property
Does this information has to do anything with the Error that I am seeing? How do go about resolving this?
You will have to declare it with the right type instead of using var:
AxWMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
var is only allowed on local variables, not on fields, and that's what the error message tells you. The error message does not mean that the field is declared in the wrong place, you just used the wrong syntax for the field type.
The MSDN says:
To correct this error
If the variable belongs at class scope, give it an explicit type.
Otherwise move it inside the method where it will be used.
So you can give the correct type while declaring the type of your variable like
IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
or else you can move the variable inside the method where it is going to be used. In your case, you can move it inside the CreatePlaylist method.
Initializing the playlist in the Constructor and passing the playlist as arguments did the trick as answered by #thumbnumkeys (now removed). Here is the code that worked for me:
namespace ABC
{
public partial class MainContentArea : Form
{
private string _currentId;
public MainContentArea(string topicId, Menu menu)
{
InitializeComponent();
_currentId = topicId;
_menu = menu;
WMPLib.IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
CreatePlaylist(_currentId, p2);
}
private void CreatePlaylist(string _currentId, WMPLib.IWMPPlaylist p2)
{
var selectedElementJumpToValue = MainContentAreaBl.GetSelectedElementValue(_currentId, "jumpTo");
string selectedElementPageTypeValue = MainContentAreaBl.GetSelectedElementPageTypeValue(selectedElementJumpToValue);
if (selectedElementJumpToValue != null)
{
_currentId = selectedElementJumpToValue;
if (_currentId != null && _currentId != "menu" && selectedElementPageTypeValue == "video")
{
var playerFile = Path.Combine(Common.ContentFolderPath, MainContentAreaBl.GetSelectedElementDataPathValue(_currentId));
p2.appendItem(axWindowsMediaPlayer.newMedia(playerFile));
axWindowsMediaPlayer.currentPlaylist = p2;
CreatePlaylist(_currentId, p2);
}
//axWindowsMediaPlayer.BringToFront();
}
axWindowsMediaPlayer.Ctlcontrols.play();
}
}
}
Others have already mentioned the problem. The specific type you would want is IWMPPlaylist, so the full line will look like this.
IWMPPlaylist p2 = axWindowsMediaPlayer.playlistCollection.newPlaylist("Playlist 1");
I am writing some unit test cases using fakes framework. I am using an object ShimFileCreationInformation from Microsoft.SharePoint.Client.Fakes namespace. Now, I pass this object to a function. Inside the function, I am trying to assign a value to the Url property.
fileCreationInformation.Url = value;
But even though the value is present, nothing gets assigned to Url properly and it remains null. Is there any workaround for this problem? To make things worse, there is not documentation available on ShimFileCreationInformation object.
Code sample:
ShimFileCreationInformation fileCreationInformation = new ShimFileCreationInformation();
SomeFunction(fileCreationInformation);
SomeFunction :
public void SomeFunction(FileCreationInformation fileCreationInformation)
{
fileCreationInformation.Url = value; // This statement had so effect on fileCreationInformation.Url
}
fileCreationInformation.Url = value;
Setting the value directly as above will not work since you are setting the value of the Shim and not the actual object. You need to use ShimFileCreationInformation.AllInstances.UrlGet so thay whenever the Url Get is called it will return the value you specify.
Your code should look something like below:
[TestMethod]
public void derived_test()
{
using (ShimsContext.Create())
{
ShimFileCreationInformation fileCreationInformation = new ShimFileCreationInformation();
ShimFileCreationInformation.AllInstances.UrlGet = (instance) => value;
SomeFunction(fileCreationInformation);
}
}
public void SomeFunction(FileCreationInformation fileCreationInformation)
{
var url = fileCreationInformation.Url;
// Check url variable above. It should be set to value
fileCreationInformation.Url = value; // This statement will not work since you are trying to set the value of the Shim and you need to use `ShimFileCreationInformation.AllInstances.UrlGet` to set property value for Shims
}
I have a GameObject we'll call the GM. Attached to it is a script that's meant to be the primary logical controller for a game.
In that script, somewhere, I have:
private dbEquipment equipment_database = new dbEquipment();
The relevant snippet from dbEquipment.cs:
public class dbEquipment {
private int total_items = 13;
private clEquipment[] _master_equipment_list;
public dbEquipment() {
_master_equipment_list = new clEquipment[total_items];
_master_equipment_list[0] = new clEquipment {
... //large amount of object initializing here
};
... //etc, for all 13 items
}
}
When I run Unity, I get:
NullReferenceException: Object reference not set to an instance of an object
Pointed at the line:
_master_equipment_list[0] = new clEquipment { ...
I tried running through the array and initializing every clEquipment object to an empty clEquipment() first:
for(int x = 0; x < total_items; x++) { _master_equipment_list[x] = new clEquipment(); }
just to be totally sure that the array was actually filled, but I got the same result.
I've also tried changing it to be a List<clEquipment>, and changing everything appropriately -- no dice.
Any ideas?
My guess is that you may been including a null reference in the section that says //large amount of object initializing here when you create a new clEquipment.
_master_equipment_list[0] = new clEquipment {
... //check for nulls here
};
You might want to post the code for the clEquipment class. You say you tried initializing every object...did you do that before the break line? If it didn't break, thats a good sign.
Also, hard to tell from your code, but do you need a "()" in the initialization where it breaks? Just a thought
_master_equipment_list[0] = new clEquipment () {