Why does the C# compiler differentiates between these 2 cases? - c#

When you have some property that's like:
using Algebra;
public Algebra.Vector3 Direction
{
get { return this.direction; }
}
then compile and later change it to:
using Algebra;
public Vector3 Direction
{
get { return this.direction; }
}
it seems like the compiled code is different between the two assemblies, which I could see using the Reflector.
Why does the compiler differentiates between the two code? Isn't it only necessary to see if there is any ambiguous type at compile time and if there isn't, have the compiled code be the same for both? I would assume the compiled code to use fully qualified names for every member at all times.

I can't reproduce this. Sample code:
namespace Algebra
{
public class Vector3 {}
}
namespace Test
{
using Algebra;
public class Program
{
private Vector3 direction = null;
public Vector3 Direction1
{
get { return direction; }
}
public Algebra.Vector3 Direction2
{
get { return direction; }
}
}
}
The generated IL for the two properties is exactly the same, and they look the same in reflector.
My guess is that you've actually got another class called Vector3 in the "global" namespace (or some other namespace that you have a using directive for).
Try hovering over both type names in Visual Studio and see what they show.

Here is an example that would generate the results you are observing. Hopefully this clears up what you’re asking. Assuming you have
a separate library containing the type Vector3 in a namespace Algebra;
the following files in your project:
File ①
namespace NotAlgebra
{
public class Vector3
{
// ...
}
}
File ②
using Algebra;
namespace NotAlgebra
{
public class XYZ
{
// Refers to NotAlgebra.Vector3 (defined in File 1 above)
Vector3 MyProperty1 { get; }
// Refers to Algebra.Vector3 (defined in the external library)
Algebra.Vector3 MyProperty2 { get; }
}
}

Related

How do I fix error CS8803? I think it might have to do with .NET 6.0 but what do I know

I'm trying to recreate Brackey's Classes tutorial from memory (checked afterwards, of course) and I've run into an issue concerning the order/placement of a fragment. Here's the code:
class Wizard
{
public static string name;
public static string spell;
public static float experience;
public static int slots;
public Wizard(string _name, string _spell)
{
name = _name;
spell = _spell;
slots = 2;
experience = 0f;
}
public void CastSpell()
{
if (slots > 0)
{
Console.WriteLine($"{name} casted {spell}.");
slots--;
experience += 0.5f;
}
else
{
Console.WriteLine($"{name} is out of spells!");
}
static void Meditate() //Used static void because public didn't work for some reason?
{
Console.WriteLine($"{name} meditates and regains all their spells!");
slots = 2;
}
}
}
Wizard wizard1 = new Wizard("Wiz Name", "Spellum lazyum");
wizard1.CastSpell();
My problem lies in the placement of these last two lines. When I have them inside the Wizard class, it gives me the error Invalid token '(' in class, record, struct, or interface member declaration. Outside, it throws Top-level statements must precede namespace and type declarations. Am I correct in thinking that the latter might happen because of the 'removal' of the Program class in .NET 6.0? I think I have an okay understand of classes, but clearly I'm missing something. Sorry if this is a simple fix; I didn't get much sleep last night.
Thank you!!
Your problem is the last two lines. These lines are executable code. Executable code must be inside a method.
Executable code is also allowed as top-level statements with specific syntax, hence the error message, but that is not relevant to your use case.
I don't know when you want to execute those two lines of code, but you probably do, so you should move them to the correct location
You have a couple of small problems. You want to support more than one wizard, so you probably want the fields to be instance rather than static. Your Meditate() is defined as a local function inside CastSpell which is not what you want. Your example usage code needs to be inside another class & method. Though you could place that within top level statements.
class Wizard
{
public string name;
public string spell;
public float experience;
public int slots;
public Wizard(string _name, string _spell)
{
name = _name;
spell = _spell;
slots = 2;
experience = 0f;
}
public void CastSpell()
{
if (slots > 0)
{
Console.WriteLine($"{name} casted {spell}.");
slots--;
experience += 0.5f;
}
else
{
Console.WriteLine($"{name} is out of spells!");
}
}
public void Meditate() //Used static void because public didn't work for some reason?
{
Console.WriteLine($"{name} meditates and regains all their spells!");
slots = 2;
}
}
public static class Program
{
public static void Test()
{
Wizard wizard1 = new Wizard("Wiz Name", "Spellum lazyum");
wizard1.CastSpell();
}
}
No. The error is not related to NET.6.0.
Code cannot exist directly within a class while being outside of methods (or field/property initializers with respect to expressions). Hence the first error message.
Code can exist as top-level statements, but as the 2nd error message tells you, any top-level statements must precede type declarations. The declaration of a class is a type declaration. Thus your top-level statements do not precede the declaration of your Wizard class, hence error.

How do I fix when it says value assigned to it is never read in C#?

Hi I'm new in programming in c#, I just want to know how to fix this issue because I can't increment the value of the points in the game that I am making...
using UnityEngine;
public class GameManager: MonoBehaviour
{
private int point;
public void IncreaseScore()
{
point++;
}
}
view image
It's just a hint, so it doesn't stop you from run this code. However to fix, as information suggests you should read point property by for example assigning it to some value:
int someValue = point;
If you want this field to be obtainable by other classes in code, you can add public method for it and adding it will resolve your issue too:
using UnityEngine;
public class GameManager: MonoBehaviour
{
private int point;
public int GetScore() => point;
public void IncreaseScore()
{
point++;
}
}

Cannot write my code right, because of an error CS0111

I'm a beginner in programming, So i don't know how to fix this error.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombieScript : MonoBehaviour
{
public Transform player;
public Transform zombie;
public GameObject zombieScript;
bool canActive = false;
void Start()
{
if (canActive == false) { zombieScript.SetActive(true); }
}
void Update()
{
UnityEngine.Debug.Log(Mathf.Abs(Vector2.Distance(player.transform.position, zombieScript.transform.position)));
if (Mathf.Abs(Vector2.Distance(player.transform.position, zombieScript.transform.position)) <= 10.00000 && canActive == false)
{
zombieScript.SetActive(true);
canActive = true;
}
}
}
Unity writes:
Assets\ZombieScript.cs(5,14): error CS0101: The namespace '' already contains a definition for 'ZombieScript'
Assets\ZombieScript.cs(12,10): error CS0111: Type 'ZombieScript'
already defines a member called 'Start' with the same parameter types
Assets\ZombieScript.cs(17,10): error CS0111: Type 'ZombieScript'
already defines a member called 'Update' with the same parameter types
in advance, thank u <3
A basic structure of a C# class looks like this:
using ...
namespace CompanyXYZ.ProductABC
{
public class Entity
{
// Constructors, properties, methods & etc.
...
}
}
CS1011 compiler error will be thrown whenever it found more than one definition within the same namespace.
Namespace allows us to avoid conflict of classes with the same name by grouping them in different namespaces.
In this case, you probably have more than one ZombieScript defined under the same namespace which is not shown in your code. Therefore, kindly check if you have it defined somewhere else (within the same namespace) and if found it you're good to go!

Why do I need fully qualified name to access static property of a class that was included with "using"

If I have this class declaration
namespace DatabaseCache
{
public class DatabaseCache
{
public static bool somePublicFlag ;
}
}
In another class I have this statement
using DatabaseCache;
Why do i need to write a statement like this in that class
DatabaseCache.DatabaseCache.somePublicFlag = true ;
instead of just
DatabaseCache.somePublicFlag = true ;
You don't need that if you don't have a Namespace and Type name collision. A well designed library will not have such collision, So design your library accordingly to avoid such collision.
namespace DatabaseCache
{
//change the name of the class
public class DifferentNameThanNamespace
{
public static bool somePublicFlag ;
}
}
Because the compiler doesn't know if DatabaseCache is referring to the namespace or the class. Even thought you're using the namespace it's still perfectly legal to preface types within that namespace by the namespace, so the call is ambiguous.
You could alias the type by using:
using DC = DatabaseCache.DatabaseCache;
and then just calling
DC.somePublicFlag
but that's just masking the problem - renaming the namespace is a better solution.
In order to avoid ambiguities, it is not recommanded to declare a class with the same same as its namespace.
The Framework Design Guidelines say in section 3.4 “do not use the same name for a namespace.
To learn about how to activate/disable this kind of warning see this link
(Of course the advice is to not use the same name for two distinct things.)
Answer with an extension. Suppose you have one file with:
namespace DatabaseCache
{
public class DatabaseCache // same name as namespace :-(
{
public static bool somePublicFlag;
}
public class somePublicFlag // evil other type
{
}
}
Then now it depends on where you put your using directives relative to your namespace. For example, in another file, this will be legal:
namespace Other
{
using DatabaseCache;
class DbcTestClass1
{
void M()
{
DatabaseCache.somePublicFlag = true; // legal!
}
}
}
In the above example, somePublicFlag refers to the field of the class!
However, this is legal as well:
using DatabaseCache;
namespace Other
{
class DbcTestClass2
{
void M()
{
var instance = new DatabaseCache.somePublicFlag(); // legal!
}
}
}
With that placing of the using directive, the somePublicFlag refers to the "evil" class of that name. The qualifier DatabaseCache. in this case is redundant, but it is still seen as a reference to the namespace global::DatabaseCache because the global namespace (null namespace) is searched first in this case.
To learn more, see my answer elsewhere. It all depends on the order in which the different namespaces (including the global namespace) are searched for a matching name.

define get or set in c#

friends i have problem with using get or set in class in c#
when i use get or set in gives error(invalid token { in class)
pls, see below code,i have this problem in it
static int abcd
{
get
{
return _abcd;
}
}
thanx
this is the complete code,i dont have this problem with any of your codes but just this:
namespace ConsoleApplication2
{
class Program
{
class Car
{
private int _speed;
public int Speed;
{
get
{
return _speed
}
}
}
}
}
The snippet you have posted is fine as it is, also in regards to the error, as it has the correct number of { to } and in the right order.
Look at where you have placed it (possibly outside of a class), or look for extra } in the file.
Update: (following edit in question)
Your issue is here:
public int Speed; // <-- ; should not be here
And:
return _speed // <-- missing the ;
The property should be implemented like this:
public int Speed
{
get
{
return _speed;
}
}
There are two errors in your code.
You have a semicolon where there shouldn't be one (spotted by Oded).
You are missing a semicolon where there should be one.
Try this instead:
namespace ConsoleApplication2
{
class Program
{
class Car
{
private int _speed;
public int Speed // <-- no semicolon here.
{
get
{
return _speed; // <-- here
}
}
}
}
}
I noticed that the code you originally posted was formatted badly. I would suggest that you format your document automatically in Visual Studio to make the braces line up. This should make the error more obvious. When the formatting of the code looks wrong you know that there is an error nearby. You can find this option in the menu: Edit -> Advanced -> Format Document or use the keyboard shortcut (Ctrl-E D for me, but might be different for you, depending on your settings).
I would also suggest that you consider using auto-implemented properties instead of writing the getter out in full:
namespace ConsoleApplication2
{
class Program
{
class Car
{
public int Speed { get; private set; }
}
}
}
This should work:
class Foo
{
static int _abcd;
static int Abcd
{
get { return _abcd; }
set { _abcd = value; }
}
}

Categories