Is there a way to reuse enums in other classes? [duplicate] - c#

This question already has answers here:
What does the using directive do, exactly?
(4 answers)
Closed 6 years ago.
Is there a way to reuse enums in other classes?
For example,
I have a class using another class's enums. However, I want to avoid having to type the other class's namespace every time I use that class's enums for my active class.

Is there a good reason why you can't just use a using statement?
using Namespace.With.Enum;
namespace Namespace.Without.Enum
{
public class Foobar
{
...
}
}
This should allow you to use the enum inside Foobar without needing to preface it.

I don't see the issue with putting a using statement at the top of each file.
namespace MyNameSpace.EnumNamespace
{
public enum MyEnum
{
One,Two,Three
}
}
And in a separate file
using MyNamespace.EnumNamespace;
namespace AnotherNamespace
{
public class AnotherClass
{
//somewhere in the same file
public void SomeMethod(MyEnum enumValue)
{
//Do stuff
}
}
}
Alternatively, you can also assign an alias as well.
using MyEnumAlias = MyNameSpace.EnumNamespace.MyEnum

If you just don't want put namespace and class name, e.g.
namespace AnotherNamespace {
...
public class AnotherClass {
...
public enum MyEnum {
One,
Two,
Three
}
}
...
}
...
namespace MyNamespace {
...
AnotherNamespace.AnotherClass.MyEnum v = ...
you can try creating synonym via using:
namespace MyNamespace {
using MyEnum = AnotherNamespace.AnotherClass.MyEnum;
...
MyEnum v = ...

Related

Compiler complaining on a missing namespace which is the name of the class

I have the following:
// Generator.cs
namespace MRP
{
public class Generator
{
public enum ModeGeneration
{
ByRequest,
ByCommit
}
}
}
// CustomerOrderWrapper.cs
namespace MRP
{
class CustomerOrderWrapper
{
readonly ModeGeneration _mode;
}
}
Why am I getting an error that the namespace name 'ModeGeneration' could not be found. Both classes are under MRP namespace, why the compiler is complaining on 'ModeGeneration' namespace?
Read the error message again. It should say something like "can't find class or namespace ModeGeneration", and it's correct, there is no class/namespace named ModeGeneration, maybe you want Generator.ModeGeneration?
As an inner class, Generator.ModeGeneration is the whole type name, and you can't omit the outer class name, because you can define a few inner classes with the same name in C# like this:
namespace Foo
{
class One
{
public class Bar { }
}
class Another
{
public class Bar { }
}
}
You can see Bar is ambiguous. You should use One.Bar and Another.Bar instead.
That is because your enum is defined in the class. Change the code as follows:
namespace MRP
{
class CustomerOrderWrapper
{
readonly Generator.ModeGeneration _mode;
}
}
There are two method to solve this problem
Method 1) You can use class name put in front of enum
namespace MRP
{
public class Generator
{
public enum ModeGeneration
{
ByRequest,
ByCommit
}
}
}
// CustomerOrderWrapper.cs
namespace MRP
{
class CustomerOrderWrapper
{
readonly Generator.ModeGeneration _mode;
}
}
Method 2) You can bring enum from in class to out namespace
namespace MRP
{
public enum ModeGeneration
{
ByRequest,
ByCommit
}
public class Generator
{
}
}
// CustomerOrderWrapper.cs
namespace MRP
{
class CustomerOrderWrapper
{
readonly ModeGeneration _mode;
}
}
I hope it will help you.
Yes they are in the same namespace, but enum ModeGeneration is also inside Generator class. So either:
Put the enum outside the Generator class and use it as you have
or
Prefix ModeGeneration in CustomerOrderWrapper.cs with Generator - Generator.ModeGeneration

namespace being shadowed

so I have a library Mine.SuperFun which calls stuff in the library SuperFun whose main namespace is SuperFun. The problem i'm having is that i can't address classes or basically anything in the SuperFun library inside classes in the Mine.SuperFun.XyZFoo namespaces
The only way to address them i have is doing stuff like:
using SuperFun_NiceClass = SuperFun.NiceClass;
using Mine.SuperFun {
...
SuperFun_NiceClass.DoStuff()
is there something i can do (besides changing the namespace in Mine library) to be able to address those classes directly?
You can use the global contextual keyword
What is the usage of global:: keyword in C#?
http://msdn.microsoft.com/en-us/library/cc713620.aspx
namespace Mine.SuperFun
{
public class My { public int a; }
}
namespace SuperFun
{
public class Theirs { public int a; }
}
namespace SomeProgram
{
public class Program
{
SuperFun.Theirs theirs;
global::Mine.SuperFun.My mine;
}
}

Assigning a value to an inherited readonly field?

So I have a base class that has many children. This base class defines some readonly properties and variables that have default values. These can be different, depending on the child.
Readonly properties/fields allow you to change the value of the variable inside the constructor and also the definition, but nowhere else. I get a 'readonly variable can only be assigned to in a constructor' error if I try to change the value of an inherited readonly variable in the child class' constructor. Why is this and how can I work around this, without Reflection?
My intention: To allow user extensibility through scripts where they can only change certain fields once.
The reason is that you can only assign to readonly fields in the constructor of that class.
According to the definition of readonly in the C# Reference (emphasis mine):
When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
To work around this, you could make a protected constructor in the base that takes a parameter for the readonly property.
An example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Base b = new Child();
Console.WriteLine(b.i);
Console.Read();
}
}
class Base
{
public readonly int i;
public Base()
{
i = 42;
}
protected Base(int newI)
{
i = newI;
}
}
class Child : Base
{
public Child()
: base(43)
{}
}
}
Adam has the right answer. If you're worried about the space it will take up (number of parameters in the constructor?) then you should address that as a different problem with a different solution: create a BaseConfig class, that contains all those properties and that is all that needs to be passed in. Base can then either assign all it's readonly fields from BaseConfig's properties, or you can instead have Base hold just one readonly field of type BaseConfig and refer to that for the values.
As to why this is, see C# constructor execution order regarding when each class's readonly fields would be initialized/initializable.
You could get the exact behavior you are looking for by using virtual get only properties.
public class BSE
{
virtual public int Prop
{
get
{
return 6;
}
}
}
public class Derived : BSE
{
public override int Prop
{
get
{
return 10;
}
}
}
Fields are out side the inheritance and overloading model and should not be used to provide polymorphic features.
You can use property with public get accessor and protected set accessor. Derived classes can set value of this property.
An example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Base b = new Child();
Console.WriteLine(b.I);
Console.Read();
}
}
class Base
{
public int I { get; protected set; }
public Base()
{
I = 42;
}
}
class Child : Base
{
public Child()
{
I = 43;
}
}
}
this is impossible by design. try passing the values to a protected base class constructor

Add reference to project in c#

I have some strange problem. I have a solution with the following structure
http://i33.tinypic.com/10fbzbq.jpg
As you can see when i wonna import the VDB.Common.RequestAndResponses it gives an error.
The namespace of dat Class Library is VDB.Common.RequestAndResponses.
I am new in c# , so it could be that i forgot something stupid.
I strongly suspect that Base.cs (the only C# file shown in the VDB.Common.RequestAndResponses project) doesn't actually declare a type in the VDB.Common.RequestAndResponses namespace - or that it only declares an internal (rather than public) type.
For example, note that the code you're creating is under the VDB.Client.Infrastructure project, but is only declaring a class in the Agatha namespace - not VDB.Client.Infrastructure.Agatha, which may be what you were intending. Do you have the same kind of thing in Base.cs, perhaps?
Without seeing the code in Base.cs, we can't see what's wrong though. If you could just post a snippet of that - just the namespace and class declaration - that would be helpful.
Note that although a class library has a default namespace, this isn't prepended to whatever the source file actually declares. In other words, in a library of Acme.Widgets, if you had a declaration of:
namespace Web
{
public class Button {}
}
that would only declare the type Web.Button, not Acme.Widgets.Web.Button.
EDIT: The OP's "answer" confirms what I thought... basically it's not declaring a namespace at all. It should look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agatha.Common;
namespace VDB.Common.RequestAndResponses
{
public abstract class BaseRequest :Request
{
// Code
}
public abstract class BaseResponse : Response
{
// Code
}
}
I would also strongly advise that these classes should be put in two separate files, BaseRequest.cs and BaseResponse.cs. I'm also pretty surprised to see a reference to Agatha.Common - shouldn't that be VDB.Common.Agatha or something like that?
Right click on the "VDB.Common.RequestAndResponses" reference in solution explorer and choose "Show in object browser", make sure the namespace is found there with the exact spelling and capitalization.
Try to use the Base class in the client code and hover over it and allow the Visual Studio IDE to prompt you to add the appropriate namespace. The namespace defined in the Base class could be different to what you think.
EDIT
As Jon as demonstrated in the 2nd part of his answer - the name of the code file does not automatically correspond to the namespace.
The Base.cs file looks like this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agatha.Common;
public abstract class BaseRequest :Request
{
public string UserName { get; set; }
public string UserDomainName { get; set; }
public string ClientLanguageCode { get; set; }
public DateTime ClientCreated { get; set; }
public DateTime ClientSent { get; set; }
public DateTime ServerReceived { get; set; }
public DateTime ServerProcessed { get; set; }
public void BeforeSend(IUserContext context)
{
ClientSent = DateTime.UtcNow;
UserName = context.UserName;
UserDomainName = context.UserDomainName;
ClientLanguageCode = context.LanguageCode;
}
}
public abstract class BaseResponse : Response
{
public DateTime ServerCreated { get; set; }
public DateTime ServerProcessed { get; set; }
public string[] ValidationErrors { get; set; }
public bool IsValid
{
get { return Exception == null & !ValidationErrors.Any(); }
}
}

How to make an object belong to a namespace (VS 2008)?

I have a name space Company.Controls, which contains several controls. I also have a class called "Common" which contains enums/structures/static methods that I use throughout the controls.
Is there a way to make these "Common" peices belong to the Company.Controls namespace this way I don't have to keep typing "Common.Structure"? Essentially having he "Common" both a namespace and a class.
Just seems messy and confusing when reading the code.
example (all the other controls are in the Blah.Controls.Common namespace)
namespace Blah.Controls
{
public enum ControlTouchState
{
Down = 0x00,
Up = 0x01,
}
public Common()
{
//Stuff here
}
}
Thanks.
You can't get exactly what you want; in C# all methods have to be in a class.
Depending on what is in your Common class, you might be able to find something a slightly more satisfying by using extension methods:
namespace Blah.Controls
{
public class CommonControl { }
public static class Common
{
public static void Foo(this CommonControl cc) { }
}
public class Control1 : CommonControl
{
public void Bar()
{
this.Foo();
}
}
}
Another thing you might consider is using partial classes which would let you write simple wrappers elsewhere:
namespace Blop.Controls
{
public static class Common
{
public static void Foo() { }
}
public partial class Control1
{
public void Bar()
{
Foo();
}
}
public partial class Control1
{
public void Foo()
{
Common.Foo();
}
}
}
Obviously, introducing some inheritence could eliminate some of the duplication; I'm assuming you don't want to do that.
Is there some reason that the nested types in Common MUST be nested? Why not separate them out into their own namespace?
namespace Common
{
public struct Structure
{
// ...
}
public enum Enumeration
{
// ...
}
public class Common
{
// ...
}
}
You could then use the Common namespace as such:
namespace Blah.Controls
{
using Common;
class Control
{
Struct myStruct;
Enumeration myEnum;
Common myCommon; // references the class, not the namespace
}
}

Categories