How can I assign an enum to a variable? - c#

I want to simplify my references to an enum:
class Order
{
enum OrderStatus{open,cancelled, onHold}
}
with something equivalent to this:
class SomeOtherClass
{
// assign enum to a simpler name
enum Status = Order.OrderStatus
public void foo(){
// so the reference is simpler, rather than Order.OrderStatus.open
Console.Write(Status.open);
}
}
Any ideas on how I can do this?

You could place this statement at the top of your source code file.
using Status = Order.OrderStatus;
Beware if you have declared your Order class in a namespace called for instance ConsoleApplication, you have to prep-end this before Order.
using Status = ConsoleApplication.Order.OrderStatus;

You can use alias directives to make this a little bit shorter. This needs to be written in the same namespace that has your SomeOtherClass.
using OrderStatus = Order.OrderStatus;

I recommend to use Enum as extra and use/reuse it everywhere your need like this:
public enum OrderStatus
{
open,
cancelled,
onHold
}
class SomeOtherClass
{
private OrderStatus Status;
public void foo(){
// so the reference is simpler, rather than Order.OrderStatus.open
Console.Write(Status.open);
}
}
If the Order is part of the "SomeOtherClass" and is relevant here please forward it in the constructor and make valid for the workflow in the foo() method.

First of all, you must make the enum public, so it is visible outside the class:
class Order
{
public enum OrderStatus { open, cancelled, onHold }
}
Then you can assign it an alias for simpler access
// give an alias
using Status = Order.OrderStatus;
class SomeOtherClass
{
public void foo(){
// reference is now simpler, rather than Order.OrderStatus.open
Console.Write(Status.open);
}
}

Related

How do I access an enum value in this class?

I am a fairly new programmer trying to make a pretty simple game by using MonoGame in C#. My problem is that I want to access an enum value (not sure if that's the right term) in this other class, but I don't know how. My guesses are that you could do something like: return Game1.State.EnterHighScore; or by making an object reference, but it has not worked for me, probably because I'm doing it incorrectly.
I would appreciate help!
I'm sorry I don't know how to format the code properly, but I tried to make it as clear as possible:
//File name: GameElements.cs
//...
//...
//...
//...
if (e.CheckCollision(player))
{
player.IsAlive = false;
return /*EnterHighScore*/; // I want to return the enum value EnterHighscore,
//..which is in the class Game1
}
//...
//...
//...
//...
//File name: Game1.cs
//...
public class Game1 : Game
{
enum State { PrintHighScore, EnterHighScore }; // I want to access EnterHighScore.
//...
}
//...
Keep your enum outside of any class. Then you can directly return from any method in any class in the same namespace.
eg:
public enum GameState
{
EnterHighScore,
EnterSomeOtherScore,
EnterLooserScore
};
public class SomeClass
{
public GameState CheckGame()
{
return GameState.EnterHighScore;
}
}
If you keep the enum inside any class, then the scope of enum will be only to that class.

C# generic return with generic type set in the method not in the call

I am trying to setup a method that retrieves data from a database, and based on data in there it will create and hydrate a class with a generic component.
public class MyObject<T> where T : BaseMyType
{
T MyTypedObject { get; set; }
}
public class MyType1 : BaseMyType
{
string Key { get; set; }
}
public class MyType2 : BaseMyType
{
Guid Id { get; set; }
}
public MyObject<T> MyMethod<T>() where T : BaseMyType
{
if(Situation1)
return new MyObject(MyType1);
else
return new MyObject(MyType2);
}
This code complains that MyObject<MyType1> cannot be converted to MyObject<T>. Now I need to use it like this:
var myObject = MyMethod();
The call of course complains it cannot infer the type from the usage. I understand the compiler error messages, I just am not sure how to do what I need.
It can't be done, but…let's suppose for a moment that we could figure out a way for the following statement to compile in the way that you want:
var myObject = MyMethod();
Then what is the code using myObject going to look like? In this hypothetical scenario, the variable myObject will sometimes have the type MyType1 and sometime have the type MyType2. Will the code using myObject care about that?
If all that code will do is use members of the shared base type (i.e. BaseMyType), then the fix is easy. Just forget about the generic approach:
public BaseMyType MyMethod()
{
if(Situation1)
return new MyType1();
else
return new MyType2();
}
If it does care about the differences (i.e. needs to access either Key or Id depending on the type that was returned), then even if you could do the impossible, the calling code is still going to need to conditionally handle the individual scenarios based on the Situation1 variable. Which would mean that you put the check for Situation1 in the wrong place.
Instead, your caller should look more like this:
if (Situation1)
{
MyType1 myObject = MyMethod1();
// do situation 1 stuff
}
else
{
MyType2 myObject = MyMethod2();
// do situation 2 stuff
}
Where the implementation of your original MyMethod() has been split into two methods, MyMethod1() and MyMethod2(), corresponding to the two scenarios. Again, note the complete lack of generics as part of the implementation. It's not called for, and won't work.
It's even possible that you need a polymorphic implementation of the caller, i.e. so you don't have to check Situation1 more than once. But without a good, minimal, complete code example it would be impossible to comment more thoroughly on that possibility.

How to hide public methods from IntelliSense

I want to hide public methods from the IntelliSense member list. I have created an attribute that, when applied to a method, will cause the method to be called when its object is constructed. I've done this to better support partial classes. The problem is that in some environments (such as Silverlight), reflection cannot access private members, even those of child classes. This is a problem since all of the work is done in a base class. I have to make these methods public, but I want them to be hidden from IntelliSense, similar to how the Obsolete attribute works. Frankly, because I am anal about object encapsulation. I've tried different things, but nothing has actually worked. The method still shows up in the member drop-down.
How do I keep public methods from showing up in IntelliSense when I don't want them to be called by clients? How's that for a real question, Philistines! This can also apply to MEF properties that have to be public though sometimes you want to hide them from clients.
Update:
I have matured as a developer since I posted this question. Why I cared so much about hiding interface is beyond me.
Using the EditorBrowsable attribute like so will cause a method not to be shown in IntelliSense:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod()
{
}
You are looking for EditorBrowsableAttribute
The following sample demonstrates how to hide a property of a class from IntelliSense by setting the appropriate value for the EditorBrowsableAttribute attribute. Build Class1 in its own assembly.
In Visual Studio, create a new Windows Application solution, and add a reference to the assembly which contains Class1. In the Form1 constructor, declare an instance of Class1, type the name of the instance, and press the period key to activate the IntelliSense drop-down list of Class1 members. The Age property does not appear in the drop-down list.
using System;
using System.ComponentModel;
namespace EditorBrowsableDemo
{
public class Class1
{
public Class1()
{
//
// TODO: Add constructor logic here
//
}
int ageval;
[EditorBrowsable(EditorBrowsableState.Never)]
public int Age
{
get { return ageval; }
set
{
if (!ageval.Equals(value))
{
ageval = value;
}
}
}
}
}
To expand on my comment about partial methods. Try something like this
Foo.part1.cs
partial class Foo
{
public Foo()
{
Initialize();
}
partial void Initialize();
}
Foo.part2.cs
partial class Foo
{
partial void Initialize()
{
InitializePart1();
InitializePart2();
InitializePart3();
}
private void InitializePart1()
{
//logic goes here
}
private void InitializePart2()
{
//logic goes here
}
private void InitializePart3()
{
//logic goes here
}
}

Reference calling assembly instance in C#

.Net 3.5 sp1 available type question ...
Is it possible to "get a handle" or reference to the actual instance of an assembly that called a method? I can get the executing and calling assembly via reflection, but what I'm after is not so much the assembly, but the INSTANCE of that assembly that called method.
Simple example (maybe):
interface IBob
{
int Id { get; }
void Foo();
}
public class Bob : IBob
{
private int _id = 123;
public int Id
{
get { return _id; }
}
public void Foo()
{
new OtherAssemblyClass().Bar();
}
}
public class OtherAssemblyClass
{
public void Bar()
{
//
// what I want to do here is get a reference
// to the calling INSTANCE of IBob and determine
// Bob's Id ... so something like:
//
// int Id = (System.XXX.GetCallingAssemblyInstance() as IBob).Id;
//
//
}
}
The real situation is a bit more complex than this, and precludes the obvious passing of IBob instance as a parameter in OtherAssemblyClass.Bar(), although that may be end result.
Entirely possible I'm just being stupid too, and not seeing obvious. 2 x 4 corrections to skull also welcome.
Unfortunately you can't get the instance unless it's passed in. You can find out what's calling your method by using the StackTrace.
PostSharp is the only way I would know of to make that work. Take a look at the InstanceBoundLaosEventArgs class. Warning: this is a pretty big deal, and a serious addition to the weight and complexity of your architecture, especially at build time.
I can get you halfway there if you are willing to use extension methods. Here's an example:
public static void Bar(this IBob CallingIBob)
{
int Id = CallingIBob.Id;
}
...and calling Bar():
public class Bob : IBob
{
#region IBob Members
public void Foo()
{
this.Bar();
}
public int Id
{
get { throw new NotImplementedException(); }
}
#endregion
}
Yes, it's not the exact case you were looking for, but functionally similar. Bar can be called from any bob and it will have a reference to the calling bob without explicitly passing in the instance.
I understand that you may want to call Bar in another assembly of your choice. Maybe Bar is defined in a base class and you are calling specific implementations of it in subclasses. That's ok, use the extension method to take in information about the specific Bar you are trying to access and route accordingly.
Please update your post with a more concrete problem definition if you would like a more specific solution.

How can one type access a private setter of another type's property?

All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)

Categories