I am new to Stack Overflow and a neophyte programmer. I am trying to build in Visual Studio 2010 C# someone else’s code as a learning opportunity. I am unable to figure out why I get the following three errors in the four classes (line 50, 59, 67, & 75) at the bottom of the attached stub code (I stripped out from the original program everything not germane to the errors):
1. “c_basic_object” Method must have a return type
2. “:” ; expected
3. “(p_name)” Invalid token ')' in class, struct, or interface member declaration
4. “p_name” The type or namespace name 'p_name' could not be found (are you missing a using directive or an assembly reference?)
The code is almost identical to the Employee and Manager classes in Andrew Troelsen’s Pro C# 2005 book in Chapter 4.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestStub
{
class Program
{
static void Main(string[] args)
{
String strTest1 = "This is a string #1";
String strTest2 = "This is a string #2";
c_basic_object objBasic = new c_basic_object(strTest1);
Console.WriteLine(objBasic.m_name);
c_abstract_button_widget objButton = new c_abstract_button_widget();
Console.WriteLine("Test, Test, Test");
Console.ReadKey(true);
Console.WriteLine();
}
}// End class Program
public class c_basic_object
{
public string m_name = String.Empty;
//Constructor create_basic_object( p_name)
public c_basic_object(string p_name)
{
m_name = p_name;
}
// create_basic_object
//Constructor construct_empty()
public c_basic_object()
{
}
// construct_empty
//# Destructor Destroy()
~c_basic_object()
{
}
} // End class c_basic_object
// -- definitions only for the Virtual Abstract functions in the factory
public class c_abstract_button_widget: c_basic_object
{
public c_basic_object(string p_name) : base(p_name)
{
//Console.WriteLine("Inside c_abstract_button_widget ");
}
} // end c_abstract_button_widget
// c_abstract_button_widget
public class c_abstract_label_widget: c_basic_object
{
public c_basic_object(string p_name) : base(p_name)
{
}
} // end c_abstract_label_widget
// c_abstract_label_widget
public class c_abstract_draw_surface_widget: c_basic_object
{
public c_basic_object(string p_name) : base(p_name)
{
}
} // end c_abstract_draw_surface_widget
// c_abstract_draw_surface_widget
public class c_abstract_scrollbar_widget: c_basic_object
{
public c_basic_object(string p_name) : base(p_name)
{
}
} // end c_abstract_scrollbar_widget
}// End namespace TestStub
The problem is here:
public class c_abstract_button_widget: c_basic_object
{
public c_basic_object(string p_name) : base(p_name)
{
//Console.WriteLine("Inside c_abstract_button_widget ");
}
}
To declare a constructor, you have to specify the class name - but you've written c_basic_object. You meant:
public class c_abstract_button_widget: c_basic_object
{
public c_abstract_button_widget(string p_name) : base(p_name)
{
//Console.WriteLine("Inside c_abstract_button_widget ");
}
}
You have the same problem in your other subclasses too.
Separately, you should absolutely start following the .NET Naming Conventions. In this case, your classes should be:
BasicObject
AbstractButtonWidget
AbstractLabelWidget
AbstractScrollbarWidget
... although given that your "abstract" classes aren't actually abstract, you possibly want to rename them more... and possibly your BasicObject should be WidgetBase (or AbstractWidget, and actually abstract...)
Your parameters should just be name instead of p_name.
I'd also recommend keeping all fields private (I'd ditch the m_ prefix as well, but if the field is private that's not so bad) - you may want to expose the name as a property.
Additionally, you hardly ever need finalizers/destructors in C#. Definitely don't start adding them until you really, really know that you need one.
“c_basic_object” Method must have a return type
You are trying to create a constructor in the derived class, but constructors should be named after the containing class, not the base class. The compiler thus treads it as a method called c_basic_object, which must have a return type.
That should fix the other compiler errors as : base(p_name) is not valied syntax for a method.
Just rename your constructors:
public class c_abstract_button_widget: c_basic_object
{
public c_abstract_button_widget(string p_name) : base(p_name)
{
//Console.WriteLine("Inside c_abstract_button_widget ");
}
}
public class c_abstract_label_widget: c_basic_object
{
public c_abstract_label_widget(string p_name) : base(p_name)
{
}
}
public class c_abstract_draw_surface_widget: c_basic_object
{
public c_abstract_draw_surface_widget(string p_name) : base(p_name)
{
}
}
public class c_abstract_scrollbar_widget: c_basic_object
{
public c_abstract_scrollbar_widget(string p_name) : base(p_name)
{
}
}
Other suggestions:
Get rid of the empty "destructor". It is rarely needed in C# (and called a "finalizer" in some contexts)
Read up on naming standards. C# is Case-sensetive so camel case is preferred to separation by underscores
Related
I have a question about why am I able to access a class (Character class), even when I am not using the namespace in which the class is defined?
The following is the code:
File Character.cs in project MagicDestroyers:
using System;
using MagicDestroyers.WeaponNS.SharpNS;
using MagicDestroyers.EnumerationNS;
using MagicDestroyers.ArmorNS.MailNS;
namespace MagicDestroyers.CharacterNS
{
public class Character
{
private static int idCounter;
private int abilityPoints;
private int healthPoints;
private int level;
private int damage;
private ChainLink bodyArmour;
private Sword weapon;
public ChainLink BodyArmour { get => bodyArmour; set => bodyArmour = value; }
public Sword Weapon { get => weapon; set => weapon = value; }
//...
//...
//...
}
}
File Melee.cs in the same project (MagicDestroyers):
namespace MagicDestroyers.CharacterNS.MeleeNS
{
//WRONG BEHAVIOR! - we are NOT "using MagicDestroyers.CharacterNS;" -
//that is, The namespace that encompasses the Character class,
//and, we are still able to access the Character class
//using MagicDestroyers.CharacterNS;
public class Melee : Character
{
}
}
In this case your inner namespace MagicDestroyers.CharacterNS.MeleeNS it's not completely unreleted with your outer one MagicDestroyers.CharacterNS, in fact as you can see the MagicDestroyers.CharacterNS is the parent of MagicDestroyers.CharacterNS.MeleeNS. This means that automatically the inner namespace inherits all the class of his father, this is the basic concept for nested namespace.
I leave you some link that I hope can clarify better:
https://learn.microsoft.com/en-gb/dotnet/csharp/programming-guide/namespaces/using-namespaces
https://www.tutorialspoint.com/What-are-nested-namespaces-in-Chash
I am trying to teach myself this so I am sure this is obvious.
I am trying to create 2 classes that I can call instances of in Program/Main. One class is a string to double tryparse method and the other will just hold variables that will be used for many things.
My problem is I can only set Main up without error if the Main Method is only holding my new instance of class statements so I am exiting code immediately.
I will post the code to the Main. Newbie code and question, any help is much appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SetupMath
{
class Program
{
public static void Main(string[] args)
//Bringing in classes to inherit methods from
{
StringToDouble IntakeParse = new StringToDouble();
SetUpVar GuitAction = new SetUpVar();
}
// new instance of the StringToDouble class
// getting variable value "action" from string to double tryparse
public class StringToDouble
{
public string action { get; set; }
//converting "action" variable to "what"
public string What
{
get { return this.action; }
set { this.action = value; }
}
}
public class SetUpVar // new instance of the SetVar class
{
public string GuitAction { get; set; }
public string What { get; set; }
//Do something code
public void Work()
{
Console.WriteLine("Please enter a number", GuitAction);
What = Console.ReadLine();
Console.WriteLine("You entered: " + What);
}
}
}
}
You are writing StringToDouble and SetUpVar classes inside the Program class scope that's why they are visible only there. If you want your classes to be visible inside the whole namespace you should write them outside of Program class
I don't understand why an explicit reference isn't required in this situation:
//SomeStaticClass.cs
namespace WhyDontINeedUsingStatement {
public static class SomeStaticClass {
public static string Thingy {
get { return "Behold! A thingy!"; }
}
}
public class SomeNonStaticClass {
public void DoSomethingUseful() {
var foo = 9;
}
}
}
// /SomeNamespace/SomeBoringClass.cs
namespace WhyDontINeedUsingStatement.SomeNamespace {
public class SomeBoringClass {
public static void DoSomething() {
var whatever = SomeStaticClass.Thingy;
var blah = new SomeNonStaticClass();
blah.DoSomethingUseful();
}
}
}
Why doesn't this require a using WhyDontINeedUsingStatement at the top? Aren't these separate namespaces, even though they start with the same thing?
I get that C# namespaces aren't quite the same thing as Java packages (and don't affect access control), but not why the second class is able to reference stuff from the first.
According to C# Language Specification Version 5.0, Section 9.2, it seems like using the . in a namespace declaration is syntactic sugar :
The qualified-identifier of a namespace-declaration may be a single
identifier or a sequence of identifiers separated by “.” tokens. The
latter form permits a program to define a nested namespace without
lexically nesting several namespace declarations. For example,
namespace N1.N2
{
class A {}
class B {}
}
is semantically equivalent to
namespace N1
{
namespace N2
{
class A {}
class B {}
}
}
So from inside of N2 you can see N1, hence why you can use it.
I need to derive from a class Tool, as I must decorate that class with another interface IToolWrapper. Unfortunately, the Tool class does not provide a copy constructor, which is why I think one cannot write the contructor of the DerivedTool like
public DerivedTool(String filename) : base(createToolFromFile(filename)) {
//...
}
Although I was quite sure it wouldn't work I tried the following:
public sealed class DerivedTool : Tool, IToolWrapper {
static bool createToolFromFile(ref Tool tool, String filename) {
tool.Dispose();
tool = null;
try {
tool = LoadFromFile(filename) as Tool;
} catch ( Exception ) {
return false;
}
return true;
}
public DerivedTool(String filename) : base() {
Tool tool = (Tool)this;
if ( !createToolBlockFromFile(ref tool, filename) ) throw new Exception("Tool could not be loaded!");
}
}
In the debugger, I see that tool as I local variable to the constructor is modified as required (b/c the catch case isn't entered), but the base part of DerivedTool (i.e. the Tool) is not affected.
How can I achieve the desired behavior?
Use combination of a private variable and implicit/explicit operator as like below:
public sealed class DerivedTool : IToolWrapper {
private Tool _tool;
public DerivedTool(String filename) : base() {
_tool = LoadFromFile(filename) as Tool;
}
public static implicit operator Tool(DerivedTool dt)
{
return dt._tool;
}
}
//Found the solution...
The problem was in fact that I have an array of register filled on creation (contructor method) and that array wasn't instanciated.
To make it short, I've been too noob to even put a break point in the constructor to see if .Net handled a first chance exception.
Thanks again for all the repliers. You have been really helpful. :)
Sorry again for my noobness
What have I learned today :
-You never know how .net will merge your partial class
-Be more aware of first chance exceptions
//STATE CHANGE 2012/01/30 17:00 or so
Sorry, I narrowed on the wrong problem. The problem explained here doesn't seem to be caused by the code provided therefore this question no longer needs to exist.
Thanks to the repliers!
//DEPRECATED, CLOSED ... W/E
I have a device which can be contacted by various registry such 0x01, 0x02, 0x03...
Also, I work in a development environment and the application I produce are oriented for our own environment in a small compagny.
To turn these registry into object I have chosen, a long time ago, to make a class which have it's constructor private to create it's own and only instance (As I understand, multi-ton design pattern).
Since there's a lot of registry now and the class file is getting huge I want to split it into parts : The property/function definitions and the multi-ton objects.
When I try to use this ex:
Register.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
public int id { get; private set; }
public string foo { get; private set; }
public string bar { get; private set; }
protected Register(RegisterEnum id, string foo, string bar)
{
this.id = (int)id;
this.foo = foo;
this.bar = bar;
}
}
}
Register.enum.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
protected enum RegisterEnum
{
reg1 = 0x01,
reg2 = 0x02 //and so on
};
}
}
Register.const.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
public static readonly Register reg1 =
new Register(RegisterEnum.reg1,"foo1","bar1");
public static readonly Register reg2 =
new Register(RegisterEnum.reg2,"foo2","bar2");
//there is plenty more
}
}
I intended to use it like
namespace DeviceManagement
{
class SomeClassA
{
public void doThisOnDevice(Device device)
{
device.doSomeStuffOn(Register.Register.reg1, SomeCommonlyUsedStrategy);
}
}
}
Here's a test I did :
namespace DeviceManagement
{
class SomeClassA
{
public void testIfNull()
{
if(Register.Register.reg1 == null)
MessageBox.Show("It is null");
}
}
}
The compilator, intellisense doesn't throw any error/warning but, when I run my project, the Register objects are never instanciated. Altough, I don't have that issue when all this code is in the same class (not partial) and obviously in the same file.
I'm kind of lost, please help me.
For starters you don't need to break it out into a partial class to have it over multiple files. If you want to lump it together then you can put it in a different sub namespace in separate files, anyway ...
It looks like a namespace issue, as you need to have Register.Register.reg1 to access the static const.
EDIT
Ok, so from the feedback and re-reading the question a few more times I get the feeling that the current design probably won't quite work all in the same class definition. I think you maybe trying to force something into some thing which won't go.
So, why not try something like this:
namespace DeviceManagement.Register
{
public class Register
{
public RegisterType Type { get; private set; }
public string Foo { get; private set; }
public string Bar { get; private set; }
public Register(RegisterType type, string foo, string bar)
{
Type = type;
Foo = foo;
Bar = bar;
}
}
public enum RegisterType
{
reg1 = 0x01,
reg2 = 0x02 //and so on
}
public static class RegisterFactory
{
private static readonly Dictionary<RegisterType, Register> _dictionary = new Dictionary<RegisterType, Register>
{
{ RegisterType.reg1, new Register(RegisterType.reg1, "foo", "bar") },
{ RegisterType.reg2, new Register(RegisterType.reg2, "foo2", "bar2") }
};
public static Register GetRegister(RegisterType type)
{
return _dictionary[type];
}
}
}
And consume the register:
public class SomeClassA
{
public void DoThisOnDevice(Device device)
{
device.DoSomeStuffOn(RegisterFactory.GetRegister(RegisterType.reg1), SomeCommonlyUsedStrategy);
}
}
You could then take it a step further and load in the registry details from a configuration file which parses it on start up of your application to, you could then choose the registry type to work on from your UI etc.
Hope I've not got the wrong end of the stick.
I copy pasted your code and it works fine for me.
My advice is to use the Class View of Visual Studio. Here you can easily see if all the partial classes are defined within the same namespace and with the exactly same class name. If not, too many namespaces or classes will appear.