How to make Option classes like GUILayoutOption? - c#

I'm wondering how to make a class similar to GUILayoutOption class where it would take a whole bunch of GUILayout's static fields as parameters.
I couldn't find my answer in Unity Docs and I was wondering if somebody has made such a construct before.
I'm trying to make something like this:
public void SomeMethod( params MyClassOption[] options )
and call it for example like this: SomeMethod(MyClass.AnimationClip(aniClipRef), MyClass.AnimationDuration(duration), MyClass.StopAllOtherAnimations);
Seems like a great and clean way to wrap code with dozens of potentially optional parameters, but I'm not sure how to define it. Can somebody write a minimalistic example or explain how it works?

You won't find stuff like these in the documentation or any tutorial. If you are curious on how something is implemented, use decompiler such as .NET Reflector and you will see how each class is implemented.
Below is a minimalist example of how to do this. Do not use this. This is only here to show exactly how this is done by Unity. It uses the param keyword and performs boxing, both which allocates memory.
Example:
MyClass.Button("Submit Button", MyClass.MinWidth(10), MyClass.MaxWidth(20),
MyClass.MinHeight(10), MyClass.MaxHeight(10));
The MyClassOption class:
public class MyClassOption
{
public Type type;
public object value;
public MyClassOption(Type type, object value)
{
this.type = type;
this.value = value;
}
public enum Type
{
minWidth,
maxWidth,
minHeight,
maxHeight,
}
}
The MyClass class:
public class MyClass
{
public static bool Button(string text, params MyClassOption[] options)
{
return showButton(text, options);
}
private static bool showButton(string text, MyClassOption[] options)
{
//Not IMPLEMENTED
//DISPLAY BUTTON THEN CHECK IF IT IS CLICKED?
return false;
}
public static MyClassOption MaxHeight(float maxHeight)
{
return new MyClassOption(MyClassOption.Type.maxHeight, maxHeight);
}
public static MyClassOption MaxWidth(float maxWidth)
{
return new MyClassOption(MyClassOption.Type.maxWidth, maxWidth);
}
public static MyClassOption MinHeight(float minHeight)
{
return new MyClassOption(MyClassOption.Type.minHeight, minHeight);
}
public static MyClassOption MinWidth(float minWidth)
{
return new MyClassOption(MyClassOption.Type.minWidth, minWidth);
}
}
Basically, you add your custom options in the enum from the MyClassOption class then you add a function that will be used to access that enum in the MyClass. That function will return new MyClassOption object.
There's too much memory allocation going on each time an option is added to a function or executed to the extent that I think it is not worth it. It is fine in a normal C# application but not in a game app which can cause hiccups due to GC.
EDIT:
Things that can be done to improve this:
1.Change the MyClassOption class to struct.
2.On the MyClassOption class constructor object value parameter, change that to c# generics. T[] value.
Now, the only problem left is the param keyword which is the only thing that allocates memory. It should be fine for some applications but this is mostly useful for Editor plugins.

Related

C# simulating a global scope to contain user-defined but runtime-constant delegate arrays

I have some delegates, two classes and a struct that look kind of like this:
delegate Value Combination(Value A, Value B);
class Environment
{
private Combination[][] combinations;
private string[] typenames;
private getString[] tostrings;
public Environment() { ... } //adds one 'Null' type at index 0 by default
public void AddType(string name, getString tostring, Combination[] combos) { ... }
public Value Combine(Value A, Value B)
{
return combinations[A.index][B.index](A, B);
}
public string getStringValue(Value A)
{
return tostrings[A.index](A);
}
public string getTypeString(Value A)
{
return typenames[A.index];
}
}
class Container
{
public string contents
{
get
{
return data.text;
}
}
public string contentType
{
get
{
return data.type;
}
}
private Value data;
public Container(Value val)
{
data = val;
}
public Container CombineContents(Container B)
{
return new Container(data.Combine(B.data))
}
}
struct Value
{
public string type
{
get
{
return environment.getTypeString(this);
}
}
public string text
{
get
{
return environment.getStringValue(this);
}
}
public readonly int type;
public readonly byte[] raw;
public readonly Environment environment;
public Value(int t, byte[] bin, Environment env)
{
type = t;
raw = bin;
environment = env;
}
public Value Combine(Value B)
{
return environment.Combine(this, B)
}
}
The reason for this structure is that Containers can have Values of various types, which combine with each other in user-defined ways according to the current Environment (which, like Container and Value, is differently named so as to avoid conflicting with the System.Environment class in my actual code- I used the name here to concisely imply its function). I cannot get around the problem with subclasses of Value and generic Containers since values of different types still need to be combinable, and neither Container nor the base Value class can know what type of Value combination should return.
It doesn't seem possible to define the Environment class in a global way, as the existing System.Environment class doesn't seem to allow storing delegates as user variables, and giving it a static method returning an instance of itself would render it unmodifiable*, and would require a new instance of the class to be created every time I want to do anything with Values, which seems like it should be a huge performance hit.
This causes two problems for me:
There is an extra reference padding out all my Values. Values are variable in size, but raw is almost always 8 bits or less, so the difference is significant, especially since in actual implementations it will be fairly common to have several million Values and Containers in memory at once.
It is impossible to define a proper 'null' Value, as a Value must have an Environment in it and the Environment must be mutable. This in turn means that Container constructors that do not take a Value as an argument are much more convoluted.
The only other way around this I can think of would be to have a wrapper class (either an extension of Environment or something with an environment as a parameter) which is required in order to work with Containers or Values, which has all extant Containers and Values as members. This would solve the 'null' problem and neaten up the Value class a bit, but adds a huge amount of overhead as described and makes for a really convoluted interface for the end user. Those problems are, with a good deal of work and some changes in program flow, solvable as well, but by that point I'm pretty much writing another programming language which is far more than I should need.
Is there any other workaround for this that I'm missing, or am I mistaken about any of my disqualifying factors above? The only thing I can think of is that the performance hit from the static implementation might be smaller than I think it would be due to cacheing (I cannot perform realistic benchmarking unfortunately- there are too many variables in how this could be used).
*Note that an environment doesn't strictly speaking need to be modifiable- there would be no problem, technically, for example, with something like
class Environment
{
private Combination[][] combinations;
private string[] typenames;
private getString[] tostrings;
public Environment(Combination[][] combos, string[] tnames, getString[] getstrings)
{
combinations = combos;
typenames = tnames;
tostrings = getstrings;
}
}
except that this would be much more awkward for the end user, and doesn't actually fix any of the problems I've noted above.
I had a lot of trouble trying to understand exactly what you were trying to achieve here! So apologies if I'm off the mark. Here is a singleton based example that, if I understand the problem correctly, may help you:
public class CombinationDefinition
{
public string Name;
public getString GetString;
public Combination[] Combinations;
}
public static class CurrentEnvironment
{
public static CombinationDefinition[] Combinations = new CombinationDefinition[0];
public static Environment Instance { get { return _instance.Value; } }
static ThreadLocal<Environment> _instance = new ThreadLocal<Environment>(() =>
{
Environment environment = new Environment();
foreach (var combination in Combinations)
environment.AddType(combination.Name, combination.GetString, combination.Combinations);
return environment;
});
public static Value CreateValue(int t, byte[] bin)
{
return new Value(t, bin, Instance);
}
}
Which can be used as:
CurrentEnvironment.Combinations = new CombinationDefinition[]
{
new CombinationDefinition() { Name = "Combination1", GetString = null, Combinations = null },
new CombinationDefinition() { Name = "Combination2", GetString = null, Combinations = null },
};
Value value = CurrentEnvironment.CreateValue(123, null);
string stringValue = CurrentEnvironment.Instance.getStringValue(value);
Important to note - CurrentEnvironment.Combinations must be set before the Environment is used for the first time as accessing the Instance property for the first time will cause the Environment to be instantiated by its ThreadLocal container. This instantiation uses the values in Combinationsto use the existing AddType method to populate the Environment.
You either need to make Environment a "Singleton" (recomended), or mark everything inside it as static. Another possibility is to use an IoC container, but that may be more advanced than you are ready to go for at this point.
The Singleton pattern usually declared a static Instance property that is initialized to a new instance of the class through a private constructor. All access is done through the static Instance property, which will be available globally. You can read more about Singletons in C# here.
static will allow you to access the members without instantiating an instance of the class and it will act as a "global" container.
Singleton Example:
class Environment
{
private static Environment _instance;
public static Environment Instance
{
get
{
if (_instance == null)
{
_instance = new Environment();
}
return _instance;
}
}
private Environment(){}
private Combination[][] combinations;
private string[] typenames;
private getString[] tostrings;
public Environment() { ... } //adds one 'Null' type at index 0 by default
public void AddType(string name, getString tostring, Combination[] combos) { ... }
public Value Combine(Value A, Value B)
{
return combinations[A.index][B.index](A, B);
}
public string getStringValue(Value A)
{
return tostrings[A.index](A);
}
public string getTypeString(Value A)
{
return typenames[A.index];
}
}
Example usage:
Environment.Instance.getStringValue(this);
Please excuse any syntax errors in code, I don't have access to Visual Studio at the moment.

how to write the methods inside the enum in c# [duplicate]

In Java, it's possible to have methods inside an enum.
Is there such possibility in C# or is it just a string collection and that's it?
I tried to override ToString() but it does not compile. Does someone have a simple code sample?
You can write extension methods for enum types:
enum Stuff
{
Thing1,
Thing2
}
static class StuffMethods
{
public static String GetString(this Stuff s1)
{
switch (s1)
{
case Stuff.Thing1:
return "Yeah!";
case Stuff.Thing2:
return "Okay!";
default:
return "What?!";
}
}
}
class Program
{
static void Main(string[] args)
{
Stuff thing = Stuff.Thing1;
String str = thing.GetString();
}
}
You can write an extension method for your enum:
How to: Create a New Method for an Enumeration (C# Programming Guide)
Another option is to use the Enumeration Class created by Jimmy Bogard.
Basically, you must create a class that inherits from his Enumeration. Example:
public class EmployeeType : Enumeration
{
public static readonly EmployeeType Manager
= new EmployeeType(0, "Manager");
public static readonly EmployeeType Servant
= new EmployeeType(1, "Servant");
public static readonly EmployeeType Assistant
= new EmployeeType(2, "Assistant to the Regional Manager");
private EmployeeType() { }
private EmployeeType(int value, string displayName) : base(value, displayName) { }
// Your method...
public override string ToString()
{
return $"{value} - {displayName}!";
}
}
Then you can use it like an enum, with the possibility to put methods inside it (among another things):
EmployeeType.Manager.ToString();
//0 - Manager
EmployeeType.Servant.ToString();
//1 - Servant
EmployeeType.Assistant.ToString();
//2 - Assistant to the Regional Manager
You can download it with NuGet.
Although this implementation is not native in the language, the syntax (construction and usage) is pretty close to languages that implement enums natively better than C# (Kotlin for example).
Nope. You can create a class, then add a bunch of properties to the class to somewhat emulate an enum, but thats not really the same thing.
class MyClass
{
public string MyString1 { get{ return "one";} }
public string MyString2 { get{ return "two";} }
public string MyString3 { get{ return "three";} }
public void MyMethod()
{
// do something.
}
}
A better pattern would be to put your methods in a class separate from your emum.
Since I came across, and needed the exact opposite of enum to string, here is a Generic solution:
static class EnumExtensions {
public static T GetEnum<T>(this string itemName) {
return (T) Enum.Parse(typeof(T), itemName, true);
}
}
This also ignores case and is very handy for parsing REST-Response to your enum to obtain more type safety.
Hopefully it helps someone
C# Does not allow use of methods in enumerators as it is not a class based principle, but rather an 2 dimensional array with a string and value.
Use of classes is highly discouraged by Microsoft in this case, use (data)struct(ures) instead; The STRUCT is intended as a light class for data and its handlers and can handle functions just fine. C# and its compiler don't have the tracking and efficiency capabilities as one knows from JAVA, where the more times a certain class / method is used the faster it runs and its use becomes 'anticipated'. C# simply doesn't have that, so to differentiate, use STRUCT instead of CLASS.

C# type of enclosing class

Is there some way to specify the type of the enclosing class declaration statically? If i had an instance, I could clearly use typeof(this), but statically I don't see a way.
Something like (where this_type is a placeholder):
public class Message
{
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(this_type));
}
Clearly, I could just use the actual type name, but I've got several classes that follow this pattern and would like something less copy/paste error prone.
You can use MethodBase.GetCurrentMethod().DeclaringType but typeof(Message) is probably the cleaner way
public class Message
{
public static readonly int SizeInBytes = Marshal.SizeOf(MethodBase.GetCurrentMethod().DeclaringType);
}
Btw, you'll get a runtime exception when you execute this code as it is trying to get the size of a managed object.
typeof(Message) would be the closest you'd get here, but I think you'd need to use a struct rather than a class to do this from what I recall.
Perhaps:
public class Message
{
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(Message));
}
This way, 'Message' can also be static.
What about an extension method on the type and get it dynamically instead of pushing it to a readonly static variable?
public static class Extensions
{
public static int SizeOfType(this System.Type tp) {
return Marshal.SizeOf(tp);
}
public static int SizeOfObjectType(this object obj) {
return obj.GetType().SizeOfType();
}
}
// calling it from a method, 2 ways
var size1 = this.GetType().SizeOfType();
var size2 = this.SizeOfObjectType();
var size3 = typeof(string).SizeOfType();
var size4 = "what is my type size".SizeOfObjectType();
After a short google search, I've seen other people using reflection to accomplish what you are talking about, but that comes with the caveat that it is probably a lot more expensive than just typing out typeof(this_type). I'd sooner recommend just typing it out.
Type t = MethodBase.GetCurrentMethod().DeclaringType
.NET: Determine the type of “this” class in its static method

Adding an extension method to Property Accessor

We are doing alot of INotifyPropertyChanged implementation in our View Models and quite frankly are getting tired of having to fire the property changed events explicitly in our code for both inconvenience and aesthetic reasons.
I want to put an extension on the setter of our property, making the resulting code look like:
public string LazyAccessor
{
get;
set.notify();
}
Is there a way to do this? Can we invent one if there isn't?
Check out NotifyPropertyWeaver. This will modify your code during the build process to have your properties implement the INotifyPropertyChanged pattern.
This is available as a Visual Studio Extension
Aspect oriented programming could be solution of your problem.
See Aspect Oriented Programming in C#.
And some examples here: http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS
Your "set.notify()" could work with some Reflection, but I don´t think this would be good solution and you will still need to implement getter and setter.
Extension methods can only be added to types. The getters and setters on automatic properties are converted into methods with backing variables by the compiler, so there is no way to put an extension method on them.
Is there a way to do this?
No, there isn't, not like you posted. Extension methods operate on types, not getters or setters.
Can we invent one if there isn't?
That would require changes to the C# specification - not a likely thing to happen.
There are other approaches that you can take to ease this - using a base class with a method that will make the boiler plate calls for you for example.
They didn't make it into 4.0, but are rumored to be included in 5.0.
I found this approach helpful.
You couldn't do it on the set itself. That is an action. You might however be able to do this:
public static class extensions()
{
public static NotifyAccessorSet(this string value) { some code }
}
public class SomeClass()
{
.....
private string mAccessor;
public string LazyAccessor{
get { return mAccessor; }
set { mAccessor = value; mAccessor.NotifyAccessorSet(); }
}
}
It's somewhat off the top of my head and keep in mind that the extension method would apply to all types string so you might want to implement your own return type and apply the extension method to it. Return that type then from lazyaccessor.
you can emulate a 'property-like' behavior without calling the event manualy by overriding the conversion operators of a custom generic struct.
The following is my solution:
public struct column<TType>
{
private TType _value;
private column(TType value) : this()
{
_value = value;
}
private void Set(TType value)
{
// Implement your custom set-behavior...
}
private TType Get()
{
// Implement your custom get-behavior...
return _value;
}
public override string ToString()
{
return _value.ToString();
}
public static implicit operator column<TType>(TType p)
{
column<TType> column = new column<TType>(p);
column.Set(p);
return column;
}
public static implicit operator TType(column<TType> p)
{
return p.Get();
}
}
I declare the struct with a generic parameter to avoid from conversion errors. You can use it like this:
public class Test
{
public column<int> kKey;
public column<float> dMoney;
public column<string> cValue;
public Test()
{
kKey = 42;
dMoney = 3.1415926f;
cValue = "May the force be with you!";
}
}
...I know, the question is outdated but it may help someone in the future.

Creating a Generic Class Member for Extra Info

I'm very new to C# (this is my first C# project). I'm fairly confident with the basics, but I'm starting to run into things that are raising issues that I can't quite solve, no matter how many different ways I Google it. A LOT of my questions have been answered by this site. :]
So, since I can't find the answer to this question, I decided to post it myself.
Maybe it's too basic of a question that everyone pretty much knows it, but I couldn't figure this out from the MSDN reading.
It has to do with C# Generics. I'm programming for a video game engine, and I've created a simple messaging system between AI units. The Message class contains members like sender, receiver, dispatchTime, and extraInfo. I want to use the extraInfo member to be a useful, flexible addition to the Message class, so I would like for it to be able to contain any type (an int node index, a double path cost, a relevant Vector3 position from XNA, etc, etc...). My research for this pointed me in the direction of Generics.
I figured out how to use Generics in something like a List, but I haven't read anything about how to just declare and implement a generic -member-. Just a single member, not a collection.
How would I declare this member, extraInfo? Additionally, when accessing it from another class, I would like to be able to type:
info = message.extraInfo;
..to retrieve the extra information via the get property.
How would this be done in C#?
Your message class would look something like this
public class Message<T>
{
public object Sender { get; set; }
public object Receiver { get; set; }
public T ExtraInfo { get; set; }
}
public static void Main()
{
Message<double> doubleMessage = new Message<double>() { ExtraInfo = 4.0d };
Message<string> stringMessage = new Message<string>() { ExtraInfo = "Hello World" };
}
Using .NET 4.0, you can make your ExtraInfo property of type dynamic. You could then store anything at all in it, and as long as you access it properly at runtime, you'll be ok.
You could declare the extraInfo member of your class as an object. You could then put anything you want in there.
You can solve your problem by creating an ExtraInfoType object that contains an
object as well as implicit operators to convert to and from the various object types transparently.
The ExtraInfoType object can also indicate what kind of object is stored in the ExtraInfoType.
An example of this implementation is below.
enum ExtraInfoKind
{
Integer,
Double
}
class ExtraInfoType
{
object value;
public object Value {
get { return value; }
}
ExtraInfoKind kind;
public ExtraInfoKind Kind {
get { return kind; }
}
private ExtraInfoType(object o, ExtraInfoKind kind){
this.value=o;
this.kind=kind;
}
public static implicit operator int(ExtraInfoType o){
if(o.kind!= ExtraInfoKind.Integer)
throw new InvalidCastException();
return (int)o.value;
}
public static implicit operator double(ExtraInfoType o){
if(o.kind!= ExtraInfoKind.Double)
throw new InvalidCastException();
return (double)o.value;
}
public static implicit operator ExtraInfoType(int o){
return new ExtraInfoType(o, ExtraInfoKind.Integer);
}
public static implicit operator ExtraInfoType(double o){
return new ExtraInfoType(o, ExtraInfoKind.Double);
}
}
/* Example
class Program
{
public static void Main(string[] args)
{
ExtraInfoType t=1;
Console.WriteLine(t.Kind);
int valueT=t;
Console.WriteLine(t);
Console.ReadLine();
}
}
*/
Here you would declare extraInfo under the type ExtraInfoType.
Note that no generics are necessary here. Note also that ExtraInfoType
can store only one kind of object, which can be determined by the Kind property.
If the object is cast to the wrong type, an InvalidCastException is thrown, as
can be seen in the implicit operators above.

Categories

Resources