Skip to content

piotrstenke/Durian

Repository files navigation

Durian logo

Durian is a collection of Roslyn-based analyzers, source generators and utility libraries that bring many extensions to C#, with heavy emphasis on features that can be found in other existing languages. It's main goal is to make C# easier and more pleasant to use through reducing necessary boilerplate code, while at the same time providing additional layers of flexibility.

Table of Contents

  1. Current State
  2. Features
    1. DefaultParam
    2. InterfaceTargets
    3. FriendClass
  3. In Progress
    1. CopyFrom
  4. Experimental
    1. ConstExpr

Current State

Durian is at an early stage of its evolution - many core features are still missing, being either in early development or planning phase. As for now, three fully-fledged modules are ready - DefaultParam, InterfaceTargets and FriendClass.

Features

To see more about a specific feature, click on its name.

DefaultParam allows to specify a default type for a generic parameter.

using Durian;

public class Test<[DefaultParam(typeof(string))]T>
{
	public T Value { get; }

	public Test(T value)
	{
		Value = value;
	}
}

public class Program
{
	static void Main()
	{
		// Test<T> can be used without type parameters - 'T' defaults to 'string'.
		Test test1 = new Test("");
		
		// Type parameter can be stated explicitly.
		Test<string> test2 = new Test<string>("");
	}
}

InterfaceTargets, similar to how System.AttributeUsageAttribute works, allows to specify what kinds of members an interface can be implemented by.

using Durian;

[InterfaceTargets(InterfaceTargets.Class)]
public interface ITest
{
}

// Success!
// ITest can be implemented, because ClassTest is a class.
public class ClassTest : ITest
{
}

// Error!
// ITest cannot be implemented, because StructTest is a struct, and ITest is valid only for classes.
public struct StructTest : ITest
{
}

FriendClass allows to limit access to 'internal' members by specifying a fixed list of friend types.

using Durian;

[FriendClass(typeof(A))]
public class Test
{
	internal static string Key { get; }
}

public class A
{
	public string GetKey()
	{
		// Success!
		// Type 'A' is a friend of 'Test', so it can safely access internal members.
		return Test.Key;
	}
}

public class B
{
	public string GetKey()
	{
		// Error!
		// Type 'B' is not a friend of 'Test', so it cannot access internal members.
		return Test.Key;
	}
}

CopyFrom allows to copy implementations of members to other members, without the need for inheritance. A regex pattern can be provided to customize the copied implementation.

using Durian;

[CopyFromType(typeof(Other)), Pattern("text", "name")]
public partial class Test
{
}

public class Other
{
	private string _text;

	void Set(string text)
	{
		_text = text;
	}
}

// Generated

partial class Test
{
	private string _name;

	void Set(string name)
	{
		_name = name;
	}
}

In Progress

The following modules are still in active development and are yet to be released in a not-yet-specified future.

Experimental

Experimental stage is a playground of sorts - modules included here are very early in development and there in no guarantee that they will be ever actually released.

ConstExpr allows a method to be executed at compile-time, producing actual constants.

using Durian;

public static class Utility
{
	[ConstExpr]
	public static int Sum(params int[] values)
	{
		int sum = 0;

		for(int i = 0; i < values.Length; i++)
		{
			sum += values[i];
		}

		return sum;
	}
}

[ConstExprSource("Utility.Sum", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, Name = "Sum_10")]
public static partial class Constants
{
}

// Generated

public static partial class Constants
{
	public const int Sum_10 = 55;
}

(Written by Piotr Stenke)

About

Durian is a collection of Roslyn-based analyzers and source generators that extend the default capabilities of C#.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages