Does C# have extension properties?
For the moment it is still not supported out of the box by Roslyn compiler ...
Until now, the extension properties were not seen as valuable enough to be included in the previous versions of C# standard. C# 7 and C# 8.0 have seen this as proposal champion but it wasn't released yet, most of all because even if there is already an implementation, they want to make it right from the start.
But it will ...
There is an extension members item in the C# 7 work list so it may be supported in the near future. The current status of extension property can be found on Github under the related item.
However, there is an even more promising topic which is the "extend everything" with a focus on especially properties and static classes or even fields.
Moreover you can use a workaround
As specified in this article, you can use the TypeDescriptor
capability to attach an attribute to an object instance at runtime. However, it is not using the syntax of the standard properties.
It's a little bit different from just syntactic sugar adding a possibility to define an extended property like string Data(this MyClass instance)
as an alias for extension method string GetData(this MyClass instance)
as it stores data into the class.
I hope that C#7 will provide a full featured extension everything (properties and fields), however on that point, only time will tell.
And feel free to contribute as the software of tomorrow will come from the community.
Update: August 2016
As dotnet team published what's new in C# 7.0 and from a comment of Mads Torgensen:
Extension properties: we had a (brilliant!) intern implement them over
the summer as an experiment, along with other kinds of extension
members. We remain interested in this, but it’s a big change and we
need to feel confident that it’s worth it.
It seems that extension properties and other members, are still good candidates to be included in a future release of Roslyn, but maybe not the 7.0 one.
Update: May 2017
The extension members has been closed as duplicate of extension everything issue which is closed too.
The main discussion was in fact about Type extensibility in a broad sense.
The feature is now tracked here as a proposal and has been removed from 7.0 milestone.
Update: August, 2017 - C# 8.0 proposed feature
While it still remains only a proposed feature, we have now a clearer view of what would be its syntax. Keep in mind that this will be the new syntax for extension methods as well:
public interface IEmployee
{
public decimal Salary { get; set; }
}
public class Employee
{
public decimal Salary { get; set; }
}
public extension MyPersonExtension extends Person : IEmployee
{
private static readonly ConditionalWeakTable<Person, Employee> _employees =
new ConditionalWeakTable<Person, Employee>();
public decimal Salary
{
get
{
// `this` is the instance of Person
return _employees.GetOrCreate(this).Salary;
}
set
{
Employee employee = null;
if (!_employees.TryGetValue(this, out employee)
{
employee = _employees.GetOrCreate(this);
}
employee.Salary = value;
}
}
}
IEmployee person = new Person();
var salary = person.Salary;
Similar to partial classes, but compiled as a separate class/type in a different assembly. Note you will also be able to add static members and operators this way. As mentioned in Mads Torgensen podcast, the extension won't have any state (so it cannot add private instance members to the class) which means you won't be able to add private instance data linked to the instance. The reason invoked for that is it would imply to manage internally dictionaries and it could be difficult (memory management, etc...).
For this, you can still use the TypeDescriptor
/ConditionalWeakTable
technique described earlier and with the property extension, hides it under a nice property.
Syntax is still subject to change as implies this issue. For example, extends
could be replaced by for
which some may feel more natural and less java related.
Update December 2018 - Roles, Extensions and static interface members
Extension everything didn't make it to C# 8.0, because of some of drawbacks explained as the end of this GitHub ticket. So, there was an exploration to improve the design. Here, Mads Torgensen explains what are roles and extensions and how they differs:
Roles allow interfaces to be implemented on specific values of a given
type. Extensions allow interfaces to be implemented on all values of a
given type, within a specific region of code.
It can be seen at a split of previous proposal in two use cases. The new syntax for extension would be like this:
public extension ULongEnumerable of ulong
{
public IEnumerator<byte> GetEnumerator()
{
for (int i = sizeof(ulong); i > 0; i--)
{
yield return unchecked((byte)(this >> (i-1)*8));
}
}
}
then you would be able to do this:
foreach (byte b in 0x_3A_9E_F1_C5_DA_F7_30_16ul)
{
WriteLine($"{e.Current:X}");
}
And for a static interface:
public interface IMonoid<T> where T : IMonoid<T>
{
static T operator +(T t1, T t2);
static T Zero { get; }
}
Add an extension property on int
and treat the int
as IMonoid<int>
:
public extension IntMonoid of int : IMonoid<int>
{
public static int Zero => 0;
}
Extension Methods on Properties in C#
Are you trying to avoid needing to call the get
and the set
separately? It would work to use just a normal extension method like
public Vector MoveX(this Vector prop, float val){...}
and then you would use it like
myLine.start = myLine.start.MoveX(2f);
Is that still more complicated than what you would want to do? If so, you could make a public method that calls the get
and set
for you and you just supply the float that you want to move by.
public void MoveStartX(float x){...}
public void MoveEndX(float x){...}
Solution using reflection... is it worth it?
If you are wanting a very generic extension that works using reflection and doesn't have to specifically use a Line
object, you could do the following
public static void MoveX<T>(this T obj, Expression<Func<T, Vector>> lambda, float x)
{
if (lambda.Body is MemberExpression memberExpression)
{
var propertyInfo = (PropertyInfo)memberExpression.Member;
var getMethod = propertyInfo.GetGetMethod();
var setMethod = propertyInfo.GetSetMethod();
if (setMethod == null || getMethod == null)
throw new ArgumentException("lambda expression must reference a settable and gettable property.");
var vector = (Vector)getMethod.Invoke(obj, null);
vector.x += x;
setMethod.Invoke(obj, new object[]{vector});
}
else
{
throw new ArgumentException("lambda expression must reference an accessible property.");
}
}
and then you can use the extension method like this
var line = new Line();
line.MoveX(l => l.start, 2);
Can an extension method be added to a class property to get the value of an attribute associated with the property?
No. Because the syntax you propose returns the value of the LastName
property and not the property itself.
In order to retrieve and make use of the attributes, you'll need to use reflection which means you need to know the property itself.
As an idea, you could achieve this neatly by using LINQ's Expression library though to resolve the property for the object.
Example syntax you might look for:
var lastNameMaxLength = AttributeResolver.MaxLength<Users>(u => u.LastName);
Where:
public class AttributeResolver
{
public int MaxLength<T>(Expression<Func<T, object>> propertyExpression)
{
// Do the good stuff to get the PropertyInfo from the Expression...
// Then get the attribute from the PropertyInfo
// Then read the value from the attribute
}
}
I've found this class helpful in resolving properties from Expressions:
public class TypeHelper
{
private static PropertyInfo GetPropertyInternal(LambdaExpression p)
{
MemberExpression memberExpression;
if (p.Body is UnaryExpression)
{
UnaryExpression ue = (UnaryExpression)p.Body;
memberExpression = (MemberExpression)ue.Operand;
}
else
{
memberExpression = (MemberExpression)p.Body;
}
return (PropertyInfo)(memberExpression).Member;
}
public static PropertyInfo GetProperty<TObject>(Expression<Func<TObject, object>> p)
{
return GetPropertyInternal(p);
}
}
extend class in c# with properties
You can have a child class derived from User class .
Ex:
public class childClass:User
{
public bool SomeBoolProperty { get; set; }
}
You can access these property like this
User _user= new ChildClass();
_user.SomeBoolProperty =10;
How do I create an extension property in C#?
You cannot (at the time of writing) extend properties in c#, and you certainly cannot extend string
seeing as it is a sealed class.
Use methods instead of properties, and make a StringExtension
class instead of inheriting string.
Can I change an extension method into a property?
Well, you've got a parameter : this Enum key
even if usage "looks like" a property, remind that
PageType.ContentBlock.D2();
is equivalent to
EnumExt.D2(PageType.ContentBlock);
so, when you need a parameter, use... a method !
Does C# have extension properties?
Related Topics
What Does Initializecomponent() Do, and How Does It Work in Wpf
How to Serialize a String as Cdata Using Xmlserializer
How to Use Nuget Packages in My Azure Functions
How to Serialize a Dictionary as Part of Its Parent Object Using JSON.Net
Order of Linq Extension Methods Does Not Affect Performance
Passing Values Between Windows Forms C#
Creating a Copy of an Object in C#
How to Elevate Privileges Only When Required
How to Get Dropdownlist Selectedvalue in Controller in MVC
How to Make Something That Catches All 'Unhandled' Exceptions in a Winforms Application
Set Timeout for Webclient.Downloadfile()
Async/Await With/Without Awaiting (Fire and Forget)
How to Create a Dto in C# ASP.NET from a Fairly Complex JSON Response
C# Okay with Comparing Value Types to Null
How to Check for Nulls in an '==' Operator Overload Without Infinite Recursion
In a "Using" Block Is a SQLconnection Closed on Return or Exception