Crap I always forget...
Using Enums
- Always declare a zero value, valid enum
- Use
ResourceDictionary
to localize them. - For flags, remember there is a limit of 31 for an int and 63 for a long.
- Microsoft docs
To create a normal Enum, use the attribute below so that serialization and deserialization values are maintained. You can optionally add an EnumMember
attribute to convert the string to specific values:
[JsonConverter(typeof(StringEnumConverter))]
public enum MyEnumType
{
[EnumMember(Value = "optionalNameValue")]
Active = 1,
Inactive = 2,
Suspended = 4
}
To get a list of the values:
Enum.GetNames(typeof(MyEnumType)).ToList()
To get a list for presentation, combine with a ResourceDictionary
Enum.GetNames(typeof(MyEnumType)).ToList().Select(e => resources[e]));
To get a case insensitive comparison:
Enum.TryParse<Foo>(myStringValue, ignoreCase: true, out MyEnumType myEnumValue);
Note: this will return 0 if the incoming myStringValue isn't valid. Therefore, always create default value for 0.
To convert from an integer to an enum:
var myEnumValue = (MyEnumType)myIntegerThatINeedConverted;
To convert an enum value to a string:
MyEnumType.Value.ToString();
// or
string enumText = Enum.GetName(typeof(MyEnumType), myIntegerValue);
To use them as flags, add the [Flags]
attribute to your enum class and use bit shifting so you don't have to do the math (never use zero in a flag):
[JsonConverter(typeof(StringEnumConverter))]
[Flags]
Enum Permissions
{
CanInvite = 1 << 0,
CanDelete = 1 << 1,
CanCreate = 1 << 2,
CanRead = 1 << 3
}
To provide multiple values, OR them together:
var permissions = Permissions.CanInvite | Permissions.CanDelete;
To delete a value, use XOR to take them out:
var permissions = permissions ^ Permissions.CanDelete;
To see if a flag is set, use the HasFlag
method:
var permissions = Permissions.CanInvite | Permissions.CanDelete;
var invitationPermitted = permissions.HasFlag(Permissions.CanInvite);
// will result in 'true'
VS 2017 Package Loading fail
MSBuild Problems for iOS and loading from different paths.
1- On Windows, open the Visual Studio 2017 installation folder. (Default: C:\Program Files (x86)\Microsoft Visual Studio\2017\<Edition>\)
2- Navigate to MSBuild\Xamarin.
3- Open the Xamarin.Apple.Sdk.targets file in an editor with Administrator privileges.
4- At the end of the file you'll find a PropertyGroup (line 100), between the PropertyGroup tags add the following line:
<FrameworkPathOverride>$(TargetFrameworkRootPath)$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)</FrameworkPathOverride>
The work-around for this issue would be:
Launch “Developer Command Prompt for VS 2017” as Administrator
Go to VS 2017 installation folder, for example:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional
gacutil -if Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.Shell.Interop.8.0.dll
A simple parallel task operation might look like this:
using System.Threading.Tasks;
void MainThreadMethod ()
{
Task.Factory.StartNew (() => wc.DownloadString ("http://...")).ContinueWith (
t => label.Text = t.Result, TaskScheduler.FromCurrentSynchronizationContext()
);
}
The key is TaskScheduler.FromCurrentSynchronizationContext() which will reuse the SynchronizationContext.Current of the thread calling the method (here the main thread that is running MainThreadMethod) as a way to marshal back calls to that thread. This means if the method is called on the UI thread, it will run the ContinueWith operation back on the UI thread.
If the code is starting tasks from other threads, use the following pattern to create a reference to the UI thread and the task can still call back to it:
static Context uiContext = TaskScheduler.FromCurrentSynchronizationContext();
If you need to invoke on the UI thread, look here
To camel case
Char.ToLowerInvariant(name[0]) + name.Substring(1)
Run an asynchronous task inside a synchronous one:
_clientSecret = Task.Run(async () => await secretService.GetSecretUsingName(B2CSecretName).ConfigureAwait(false)).GetAwaiter().GetResult();
Without Yield
public static IEnumerable<int> GreaterThan(int[] arr, int gt)
{
List<int> temp = new List<int>();
foreach (int n in arr) {
if (n > gt) temp.Add(n);
}
return temp;
}
With Yield (from Telerik)
public static IEnumerable<int> GreaterThan(int[] arr, int gt)
{
foreach (int n in arr) {
if (n > gt) yield return n;
}
}
Throw exception in expressions
class Student
{
private string studentName;
// Expression – Bodied Constructor -- Throw Exception
public Student(string name) => studentName = name ?? throw new ArgumentNullException();
}
or
// Expression - Properties - Throw Exception
public string Name
{
get => studentName;
set => studentName = value ?? throw new ArgumentNullException();
}
Turning a collection of objects into a List of objects
List<object> entityList = (objCollection as IEnumerable<object>).Cast<object>().ToList();
Getting an attribute from a class when you only have an instance (Core & 4.61)
The example attribute here is 'MergeableContentAttribute'
HtmlClass = entity.GetType().GetTypeInfo().GetCustomAttribute<MergeableContentAttribute>().HtmlClass
Reinstantiating an object from it's name and JSON string
var qualifiedName = Type.GetType(message.NotificationObject.Name);
var objectForNotification = (ObjectForNotification)JsonConvert.DeserializeObject(message.NotificationObject.SerializedObject, qualifiedName);