C#: Protection Level error - c#

//Page 40: Unit Test for Player class
//Player must have a health that is greater than 0
//When the character is created.
namespace UnitTestingSample
{
class PlayerTests
{
public bool TestPlayerIsAliveWhenBorn()
{
Player p = new Player(); //ERROR: 'UnitTestingSample.Player.Player()' is inaccessible due to its protection level
if (p.Health > 0)
{
return true; //pass test
}
return false; //fail test
}//end function
}//end class
}//end namespace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//Page 41
//Player class has default health which is 10
//when his character is created
namespace UnitTestingSample
{
class Player
{
public int Health { get; set; }
Player() //constructor
{
Health = 10;
}
}
}
===============
You see, this is what makes me sad.
This code comes from Book named "C# Game Programming: For Serious Game Creation".
I got an exactly same code from the CD-ROM of this book. That sample code is fine while mine has an error.
This is my first time to write game-coding using C#. However, as I understood, mine should work. But, looks like compiler does not think so.
How can I fix this?

I had a similar problem and found this blog article was very helpful
http://softwareonastring.com/316/why-cant-my-test-access-a-public-constructor
The specific solution it suggests is to add the following line to the project you want to test AssemblyInfo.cs file
[assembly: InternalsVisibleTo("TestProject")]
(Where TestProject is changed to the name of your test project assembly)
As well as right clicking on the references in your unit test project and adding a reference to the project you are testing.
This is only recommended for unit tests as it couples the two projects together tightly and would work against normal object oriented best practice.

class Player
{
public int Health { get; set; }
public Player() //constructor
{
Health = 10;
}
}
Class members are private by default and so is your constructor - which results in being inaccessible by your testing code. Make the constructor public if you want to access it from somewhere else than the class itself.

Related

CS0246 error while trying to create xUnit tests

I'm not even trying to test anything there yet, just wanted to create an instance of class Book(that I would like to test in the future) in my testing BookTests.cs file. I've added reference to GradeBook.Tests.csproj as whole source code to Gradebook is in the other folder. Yet it still returns CS0246 error : The type or namespace name 'Book' Could not be found.
Are you missing a using directive of assembly reference?
Gradebook.Tests.csproj with directory tree
using System.Collections.Generic;
namespace Gradebook
{
public class Book
{
private List<double> grades;
private string name;
public Book(string name)
{
this.name = name;
grades = new List<double>();
}
public void AddGrade(double grade)
{
grades.Add(grade);
}
}
}
Book.cs
using System;
using Xunit;
namespace GradeBook.Tests
{
public class BookTests
{
[Fact]
public void Test1()
{
//arrange
var book2 = new Book("test");
}
}
}
BookTests.cs
The code is pretty simple as I'm following Pluralsight course C# Fundamentals and I did everything like on the video. Tried also dotnet restore command. Path to project that contains Book.cs is probably correct(when i change something other errors occur). Working on VSC. What am I missing here?
I know it's been 2 months since this has last had an update, but the reason you're having an issue is because you're using the namespace Gradebook in Book.cs, but using GradeBook in BookTests.cs. (Notice the capital B)
Rename it so they're both Gradebook and ensure your directory names are correct and you should have no issues.

How to change the Unity Post Processing Layer Anti Aliasing Type Through C#

Im wondering How to change the Unity Post Processing Layer Anti Aliasing Type Through C#, I have tried everything but can't figure it out.
I looked through the code for the layer script but still cant figure it out.
I have tried:
MainL.antialiasingMode = Antialiasing.[Setting];
[Setting] = An Antialiasing setting.
But that hasn't worked.
code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
public class GameQuality : MonoBehaviour
{
public Camera Main;
public PostProcessVolume MainV;
public PostProcessProfile Less;
public PostProcessProfile High;
public PostProcessProfile Ultra;
public PostProcessLayer MainL;
// Use this for initialization
void Awake()
{
QualitySettings.GetQualityLevel();
if(QualitySettings.GetQualityLevel() > 2)
{
MainV.profile = Less;
}
if(QualitySettings.GetQualityLevel() == 3)
{
MainV.profile = High;
}
if(QualitySettings.GetQualityLevel() == 4)
{
MainV.profile = Ultra;
}
}
// Update is called once per frame
void Update ()
{
}
}
You can use Post​Process​Layer.antialiasingmode with a value of PostProcessLayer.Antialiasing (make sure to use the full type name including the PostProcessingLayer.)
MainL.antialiasingMode = PostProcessingLayer.Antialiasing.XY;
where XY can be one out of None, FastApproximateAntialiasing, SubpixelMorphologicalAntialiasing or TemporalAntialiasing.
Note that this allone might not be enough. You might also have to set the values of the according antialiasing MainL.temporalAntialiasing, MainL.fastApproximateAntialiasing or MainL.subpixelMorphologicalAntialiasing.
Btw you should remove the first call of
QualitySettings.GetQualityLevel();
it just does nothing

Visual Studio 2017 intellisense includes full namespace

Assuming I have two classes called Job and Person with a property called Jobs that is a List<Job>. Inside the constructor when I create a new List<Job> using intellisense it automatically adds the full namespace this.Jobs = new List<Demo.Namespace.Job>(). I just want it to be like this: this.Jobs = new List<Job>(). Any ideas how to solve this?
public class Job
{
}
public class Person
{
public Person()
{
this.Jobs = new List<Demo.Namespace.Job>() // this should be ... new List<Job>();
}
public List<Job> Jobs { get; set; }
}
2 ways of doing that:
Add Manuallu an using
using Demo.Namespace;
on top of the class
Use CTRL+. autocompletion
First put the cursor on the object Job and press CTRL+., then pur an using statement with the first menu options (it's the same as point 1).
That will avoid you to have to specify a full namespace every time.
IF YOU ALREADY KNOW THIS, then you have namespace ambiguity.
Try to just put List as you want to do and check what it says in the error window, it will tell you whatever other class is creating ambiguity, then you will have to adapt the namespaces to be different

Dynamically creating a CustomEditor class in Unity / C#

I am trying to implement edit-mode scripts in my Unity project. The idea is that a script can be attached to an object and as it's edited, attributes like scale/position/rotation can be seen updating.
Without writing an edit mode script, all this stuff is possible, but the changes are not visible until the play button is pressed. That's the difference here.
I'm using a variation of the script provided here to do this.
First of all I have a MonoBehavior script attached to my game object - it looks like so:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class FlippersEditMode : MonoBehaviour {
public float extraScale = 1f;
public void updateEditorState() {
transform.localScale = (Vector3.up * extraScale);
}
}
Second I have a script in the Editor folder that calls this updateEditorState method whenever a "Update" button is pressed:
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(FlippersEditMode))]
public class FlipperEditModeMeta: Editor {
public override void OnInspectorGUI() {
base.OnInspectorGUI();
if (GUILayout.Button("Update")) {
if (target.GetType() == typeof(FlippersEditMode)) {
FlippersEditMode flippers = (FlippersEditMode)target;
flippers.updateEditorState();
}
}
}
}
This works fine and I'm thankful for that, but this last chunk of code is pure boilerplate. I will need to have a nearly-identical one of these files for each script that I want to effect edit mode.
So I started on trying to make a "meta" editor script. The idea is that this script would have an array of slots that the developer can drag scripts into. Each script dragged here will get a CustomEditor class defined like the one shown above. Of course the classes being dragged here would each need to implement updateEditorState but that's the only requirement of the protocol.
So if I make another editor script that looks like this:
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(EditModeScripts))]
public class EditModeScriptsMeta : Editor {
public override void OnInspectorGUI() {
base.OnInspectorGUI();
if (GUILayout.Button("Update")) {
if (target.GetType() == typeof(EditModeScripts)) {
EditModeScripts edit_mode_scripts = (EditModeScripts)target;
edit_mode_scripts.updateEditorState()
}
}
}
}
Then I can trigger the updateEditorState function in the following:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class EditModeScripts : MonoBehaviour {
public MonoBehaviour[] scripts = {};
public void updateEditorState () {
for (int i = 0; i < scripts.Length; i++) {
MonoBehaviour script = scripts[i];
// How to generate an editor class here for each script?
}
}
}
But as you can see I don't know how to dynamically generate the classes.
I don't think your approach will work purely dynamically. Unity compiles your code everytime you change something and come back to unity. After compiling it Unity uses Reflection to determine which editors are available.
You could theoretically create new source files which contain the editor code. I don't know though whether it will automagically reimport the scripts or you need to manually trigger the reimport.
For manually reimporting you can use a combination of AssetDatabase.Refresh() and if that is not enough, select the script asset via the Selection class and trigger the reimport menu entry using EditorApplication.ExecuteMenuItem.

namespace not being recognized?

I created a very very simple domain layer in visual studio (2010). I then used the new test wizard to create a basic unit test. However when I try to put in the using statement so that I can test my code.. it says my namespace could not be found... This is my first time using visual studio so I am at a loss as to what I am doing wrong.
My code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Home
{
class InventoryType
{
/// <summary>
/// Selects the inventory type and returns the selected value
/// </summary>
public class InventorySelect
{
private string inventoryTypes;
public String InventoryTypes
{
set
{
inventoryTypes = value;
}
get
{
return inventoryTypes;
}
}
/// <summary>
/// Validate that the inventory is returning some sort of value
/// </summary>
/// <returns></returns>
public bool Validate()
{
if (InventoryTypes == null) return false;
return true;
}
}
}
}
My Test Code
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Home.InventoryType.InventorySelect;
namespace HomeTest
{
[TestClass]
public class TestInventoryTypeCase
{
[TestMethod]
public void TestInventoryTypeClass()
{
InventorySelect select = new InventorySelect();
select.inventoryTypes = "Collection";
if (Validate() = true)
Console.WriteLine("Test Passed");
else
if (Validate() = false)
Console.WriteLine("Test Returned False");
else
Console.WriteLine("Test Failed To Run");
Console.ReadLine();
}
}
}
using refers to a namespace, not a specific class (unless you add an alias for the class name). Your using statement should only include the word Home.
using Home.InventoryType.InventorySelect;
//becomes
using Home;
Here is a link to MSDN on using directive: using Directive (C#)
I'm assuming your test class is in its own project, so you need to add a reference to that project. (A using statement doesn't add a reference, it merely allows you to use a type in your code without fully qualifying its name.)
Declare InventoryType class as public
InventorySelect class can be private rather than public
When you create a "multi-project" in a solution (by adding projects to any existing solution), the projects do not know about each other.
Go to your test project on Solution Explorer and under "References", right click and select "Add Reference". Then select "project" tab and you will be able to add your project's reference to the test project.
Also, make sure you define the classes in the project as "public" to be able to access them in test project.
namespace Home
{
public class InventoryType
{
...
}
}
Note that you still need the "using" keyword on top of your C# test class:
using Home;
namespace HomeTest
{
public class TestInventoryTypeCase
{
...
}
}

Categories

Resources