Pass a property

71 views
Skip to first unread message

Peter Morris

unread,
Feb 3, 2008, 3:24:33 AM2/3/08
to
Hi all

Is there a way to do this?

[MyCustomAttribute(ClassName.PropertyName)]

At the moment I use strings, but if the property name on the class changes
it causes runtime errors whereas I would prefer compile time errors. To be
clear, I want the name of the property and not the value of a property of an
instance.


Thanks

Pete


Marc Gravell

unread,
Feb 3, 2008, 5:06:26 AM2/3/08
to
No.

It is often discussed whether a nameof(...) operator would be a good
thing, for exactly this reason - but no such thing as yet.

Perhaps the best I can suggest is a bit of code that runs in debug
mode and uses reflection to find all members with this attribute, and
ensures that the cited property exists... i.e. it'll tell you at debug
if you have broken something...

Marc

Peter Morris

unread,
Feb 3, 2008, 5:48:49 AM2/3/08
to
Oh well, thanks :-)


Jon Skeet [C# MVP]

unread,
Feb 3, 2008, 9:51:29 AM2/3/08
to
Marc Gravell <marc.g...@gmail.com> wrote:
> It is often discussed whether a nameof(...) operator would be a good
> thing, for exactly this reason - but no such thing as yet.

It's been discussed in the C# team as well, as "infoof" - pronounced
"in-foof" of course :)

It's just never been at the top of the priority list, as I understand
it.

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk

Peter Morris

unread,
Feb 3, 2008, 10:02:08 AM2/3/08
to
> It's just never been at the top of the priority list, as I understand
> it.

I wish they would. Passing the ID of a class member is just as useful as
passing a typeof. The compiler could just make it a MethodInfo etc
depending on the member.


Jon Skeet [C# MVP]

unread,
Feb 3, 2008, 10:39:08 AM2/3/08
to

Indeed, it would certainly be useful. We shall have to see what the
future holds. The C# team certainly has no lack of potential features
to implement...

Marc Gravell

unread,
Feb 4, 2008, 3:24:01 AM2/4/08
to
> I wish they would.  Passing the ID of a class member is just as useful as
> passing a typeof.  The compiler could just make it a MethodInfo etc
> depending on the member.

I agree that a MemberInfo (perhaps auto-typed by the member) would be
truly useful in standard code - but it could be a bit problematic for
use in attributes (the OP) - there are some thorny chicken/egg edge
cases (two members that "refer" to each-other in this way via
attributes). Perhaps (in our shiny wishing world) two such; one for
just the name (useful for data-binding etc), and one for the
MemberInfo. But then of course you'd need to be able to disambiguate
overloads etc... perhaps just the name and do the rest with
reflection... I can't see any pretty ways of qualifying the member
otherwies...

Marc

Marc Gravell

unread,
Feb 4, 2008, 4:00:14 AM2/4/08
to
OK, this next is largely "for jollies", but heck, it does what we are
talking about [type-safe access giving name or MemberInfo]; uses C# 3
and .NET 3.5 though...

Of course, it won't work in attributes, so it doesn't help the OP
any...

Marc

using System;
using System.Reflection;
using System.Linq.Expressions;

static class Program
{
static void Main()
{
string test1 = MemberUtil.MemberName<Foo, string>(x => x.Bar);
string test2 = MemberUtil.MemberName<Foo, int>(x =>
x.Bloop());
string test3 = MemberUtil.MemberName<Foo>(x => x.Blap());
string test4 = MemberUtil.MemberName<Foo>(x => x.Blip(5)); //
can ignore ret...
}
}
class Foo
{
// "throws" to illustrate never invoked
public string Bar
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int Bloop() { throw new NotImplementedException(); }
public decimal Blip(int someArg) { throw new
NotImplementedException(); }
public void Blap() { throw new NotImplementedException(); }
}
static class MemberUtil
{
public static string MemberName<TType,
TResult>(Expression<Func<TType, TResult>> member)
{
return MemberInfo(member).Name;
}
public static MemberInfo MemberInfo<TType,
TResult>(Expression<Func<TType, TResult>> member)
{
return ParseMemberInfo(member);
}
public static string MemberName<TType>(Expression<Action<TType>>
member)
{
return MemberInfo(member).Name;
}
public static MemberInfo
MemberInfo<TType>(Expression<Action<TType>> member)
{
return ParseMemberInfo(member);
}
static MemberInfo ParseMemberInfo(Expression expression)
{
while (expression.NodeType == ExpressionType.Lambda)
{
expression = ((LambdaExpression)expression).Body;
}
switch (expression.NodeType)
{
case ExpressionType.MemberAccess:
return ((MemberExpression)expression).Member;
case ExpressionType.Call:
return ((MethodCallExpression)expression).Method;
default:
throw new NotSupportedException("Unable to parse " +
expression.NodeType.ToString());
}
}
}

Marc Gravell

unread,
Feb 4, 2008, 4:09:10 AM2/4/08
to
> OK, this next is largely "for jollies"

In fact, add in some "this TType obj" and you get type inference...
only useful for instance-types, of course...

Foo foo = null; // never used
string test1 = foo.MemberName(x => x.Bar);
string test2 = foo.MemberName(x => x.Bloop());
string test3 = foo.MemberName(x => x.Blap());
string test4 = foo.MemberName(x => x.Blip(5)); // can ignore
ret...

MemberInfo mi = foo.MemberInfo(x => x.Bar);

Anyway, I'm off to find a life...

Marc

Jon Skeet [C# MVP]

unread,
Feb 4, 2008, 4:51:31 AM2/4/08
to
Marc Gravell <marc.g...@gmail.com> wrote:

<snip>

> Anyway, I'm off to find a life...

If it's any consolation, this use for expression trees is one that was
already going to go on my book's web site under "notes" after the tech
reviewer mentioned it. Now I've got a more concrete example to include,
so thanks :)

Marc Gravell

unread,
Feb 4, 2008, 5:14:38 AM2/4/08
to
> this use for expression trees is one that was
> already [snip] after the tech reviewer mentioned it.

Darn; pipped to the post again... still: an interesting use, and
reassuring to know it isn't too far off the wall ;-p

I've got an updated sample that handles ctors, statics, abstracts, sub-
invokes, etc - let me know (perhaps off-group) if you want the snippet
(it isn't anything spectacular).

Marc

Reply all
Reply to author
Forward
0 new messages