C# Extension methods on "members" - c#

I have some extension methods which could be used like this:
MyType myObject;
string displayName = myObject.GetDisplayName(x => x.Property);
The problem here is that it needs an instance, even if the extension method only needs the type MyType. So if there is no instance, it needs to be called like this:
string displayName = BlahBlahUtility.GetDisplayName((MyTpe x) => x.Property);
Which is not so nice anymore.
Is there a way to write better syntax for such cases?
What I actually want to do is this (pseudo language):
string displayName = MyType.Property.GetDisplayName()
Which of course does not work with C#.
But what about something like this:
string displayName = ((MyType x) => x.Property).GetDisplayName();
This is also not possible (after a lambda, a dot is not accepted).
Any ideas?
Edit:
My "favorite syntax" MyType.Property.GetDisplayName() seems to be misleading. I don't talk about static properties here. I know that this syntax won't be possible. I just tried to show in pseudo language, what information is necessary. This would be ideal, every additional stuff is just syntactical overhead. Any working syntax that is close to this would be great.
I don't want to write a certain extension method. I want an easy, readable and compile time safe syntax, using any language feature.

Have a look at the Express and Reflect classes in the Lokad Shared Libraries. Think they may help out with what you are trying to do. Read more here:
Strongly Typed Reflection in Lokad Shared
How to Find Out Variable or Parameter Name in C#?

From your comment: "I want an easy and compile time safe syntax to get information about members".
This is a very frequently requested feature and has been discussed in the C# team's meetings for about a decade, but has never been prioritised high enough to be included.
This blog post explains why:
http://blogs.msdn.com/ericlippert/archive/2009/05/21/in-foof-we-trust-a-dialogue.aspx
So for now, you're just going to be fighting against a missing feature. Maybe you could post more information about your broader problem and see if people can suggest different approaches.
Update
Without more info about your problem this is just guesswork. But if you have a property that represents a value but also carries additional "meta" information, you could always represent that as a new type and use an "injection" step to set everything up.
Here's a suggested abstract interface to such a "meta property":
public interface IMetaProperty<TValue>
{
TValue Value { get; set; }
string DisplayName { get; }
event Action<TValue, TValue> ValueChanged;
}
The value of the property is just another sub-property, with its type defined by the user.
I've put in the display name, and also as a bonus you've got an event that fires when the value changes (so you get "observability" for free).
To have properties like this in a class, you'd declare it like this:
public class SomeClass
{
public IMetaProperty<string> FirstName { get; private set; }
public IMetaProperty<string> LastName { get; private set; }
public IMetaProperty<int> Age { get; private set; }
public SomeClass() { MetaProperty.Inject(this); }
}
Note how the setters on the properties are private. This stops anyone from accidentally setting the property itself instead of setting the Value sub-property.
So this means the class has to set up those properties so they aren't just null. It does this by calling a magic Inject method, which can work on any class:
public static class MetaProperty
{
// Make it convenient for us to fill in the meta information
private interface IMetaPropertyInit
{
string DisplayName { get; set; }
}
// Implementation of a meta-property
private class MetaPropertyImpl<TValue> : IMetaProperty<TValue>,
IMetaPropertyInit
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
var old = _value;
_value = value;
ValueChanged(old, _value);
}
}
public string DisplayName { get; set; }
public event Action<TValue, TValue> ValueChanged = delegate { };
}
public static void Inject(object target)
{
// for each meta property...
foreach (var property in target.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition()
== typeof(IMetaProperty<>)))
{
// construct an implementation with the correct type
var impl = (IMetaPropertyInit)
typeof (MetaPropertyImpl<>).MakeGenericType(
property.PropertyType.GetGenericArguments()
).GetConstructor(Type.EmptyTypes).Invoke(null);
// initialize any meta info (could examine attributes...)
impl.DisplayName = property.Name;
// set the value
property.SetValue(target, impl, null);
}
}
}
It just uses reflection to find all the IMetaProperty slots hiding in the object, and fills them in with an implementation.
So now a user of SomeClass could say:
var sc = new SomeClass
{
FirstName = { Value = "Homer" },
LastName = { Value = "Simpson" },
Age = { Value = 38 },
};
Console.WriteLine(sc.FirstName.DisplayName + " = " + sc.FirstName.Value);
sc.Age.ValueChanged += (from, to) =>
Console.WriteLine("Age changed from " + from + " to " + to);
sc.Age.Value = 39;
// sc.Age = null; compiler would stop this
If you're already using an IOC container you may be able to achieve some of this without going directly to reflection.

It looks like you're trying to create a static extension method?
DateTime yesterday = DateTime.Yesterday(); // Static extension.
Instead of
DateTime yesterday = DateTime.Now.Yesterday(); // Extension on DateTime instance.
If this is what you're trying to pull off, I do not believe it is possible in the current version of C#.

It sounds like you are integrating layers a little too tightly. Normally in this type of situation I would let the presentation layer decide the implementation of GetDisplayName() instead of making it an extension of the property itself. You could create an interface called MyTypeDisplayer or whatever you fancy, and let there be multiple implementations of it not limiting you to a single display implementation.

The issue here is that one cannot get a reference to non-static methods via instance MyType.[Member]. These can only be seen through a reference to an instance of the type. You also cannot build an extension method on-top of a type declaration, only on an instance of a type - that is the extension method itself has to be defined using an instance of a type (this T x).
One can however define the expression like this to get a reference to static members:
((MyType x) => MyType.Property)
One could do something similar to string displayName = ((MyType x) => x.Property).GetDisplayName();
The first issue is guaranteeing that the compiler treats your (x=> x.Property) as an Expression rather than an action/func etc...
To do this one might need to do this:
string displayName = ((Expression<Func<PropertyType>>)((MyType x) => x.Property).GetDisplayName();
The extension method would then have to be defined like this:
public static string GetDisplayName<T>(this Expression<Func<T>> expression)
You might also have to define an extension method on top of Expression<Action>> and Expression<Action<T>> if your members are also methods.
You can do a dot after an Expression - this is where the Compile method would reside.
Appended:
I think the static call to the extension method in cases that one doesn't have an instance of the type one needs to do "reflection" on to determine a Members name would be the cleanest syntax still - this way you could still use the extension method when using an instance of a type and fall back to the static call definition => MyExtensionClass.GetDisplayName(TypeOfX x => TypeOfX.StaticMember OR x.Property/Member) when one doesn't have an instance

If you interface your properties, you could make the extension on the interface instead:
namespace Linq1
{
class Program
{
static void Main(string[] args)
{
MyType o = new MyType();
o.Property.GetDisplayName();
}
}
public class MyType
{
public IDisplayableProperty Property { get; set; }
}
public interface IDisplayableProperty
{
string GetText();
}
public class MyProperty1 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public class MyProperty2 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public static class Extensions
{
public static string GetDisplayName(this IDisplayableProperty o)
{
return o.GetText();
}
}
}

Related

Generically get the name of the current class?

When logging data, I want a generic reference to the containing class. That way, if the code is moved elsewhere, the class name will change accordingly. (Otherwise, if the code moves to nameof(Class2), it will still be logged incorrectly as nameof(Class1)). For example:
class Class_Name {
ICommand Command_Name =>
new RelayCommand(() =>
{
// An loggable event occurs
// Is there a smart and uncomplicated way of doing this generically?
var provenance = $"{nameof(Class_Name)}.{nameof(Command_Name)}";
// The event of whatever kind gets logged
});
}
// OR
void Method_Name() {
var provenance = $"{nameof(Class_Name)}.{nameof(Method_Name)}";
}
}
Using a generic nameof(this), where this should refer to the class itself, causes a compilation error: CS8081: Expression does not have a name. Using this.GetType() causes the same problem.
Not really understanding why the this keyword does not refer to the containing class in this context. Is there a way to refer to the current class generically?
If you combine the suggestion in the comments (this.GetType().Name) with a [CallerMemberName] attribute via a helper method, you can accomplish what you're looking for in a reusable fashion.
public class Class_Name
{
public void Method_Name()
{
var provenance = CreateProvenance();
Console.WriteLine(provenance);
}
private string CreateProvenance([CallerMemberName] string methodName = "")
{
return $"{this.GetType().Name}.{methodName}";
}
}
This outputs "Class_Name.Method_Name".
You can even turn this into a handy extension method that allows you to call it from any method.
public class Class_Name
{
public void Method_Name()
{
var provenance = this.CreateProvenance();
Console.WriteLine(provenance);
}
}
public static class ProvenanceExtensions
{
public static string CreateProvenance(this object context,
[CallerMemberName] string methodName = "")
{
return $"{context.GetType().Name}.{methodName}";
}
}
As Jeppe Stig Nielsen pointed out, you may not want the inheriting runtime type to be used, which is what context.GetType().Name will return. If you want to get the compile-time type instead, you can use generics.
public static class ProvenanceExtensions
{
public static string CreateProvenance<T>(this T context,
[CallerMemberName] string methodName = "")
{
return $"{typeof(T).Name}.{methodName}";
}
}
By design:
A nameof expression is evaluated at compile time and has no effect at
run time.
To access the type dynamically, in the runtime, you may use the GetType method. Just rememeber not to combine it with the nameof.
class Class_Name {
void Method_Name() {
// An event occurs
// Is there a smart and uncomplicated way of doing this generically?
var provenance = $"{this.GetType().Name}.{MethodBase.GetCurrentMethod().Name}";
// The event of whatever kind gets logged
}
}

Setting the propery, when not knowing which one

Say I have this class with a few members, for example (this is a contrived example, I'd rather no have a discussion about the intricacies of the real-life design. I really just want to convey the general idea here.):
public class Address
{
public Guid Id { get; set; }
public Guid? HouseId { get; set; }
public Guid? FlatId { get; set; }
public Guid? SomeOtherBuildingTypeId { get; set;
}
Now as it happens there exist 3 methods to create an Address:
public void CreateAddressForHouse();
public void CreateAddressForFlat();
public void CreateAddressForSomeOtherBuildingType();
Under the surface this group of methods does the exact same thing, bar setting a different Id property in the Address class. This is causing quite some code duplication in the real life application and I want to rewrite this to something more general.
In my mind I can pass the name of the required property and its value to a CreateAddress function, in something like a Func. But I'm seriously lacking in this respect, where to start? What .NET stuff can I use out of the box? Or what specific keywords should I look for?
You can use a MemberExpression:
public void CreateAddress(Expression<Func<Address, Guid?>> member)
{
// Get the property from the expression
var propertyInfo = GetPropertyInfo(this, member);
// Create a new address
var guid = Guid.NewGuid();
// Assign it to the property of this instance
propertyInfo.SetValue(this, guid);
}
Then you call the method like this, using a lambda a => a.PropertyName:
var address = new Address();
address.CreateAddress(a => a.HouseId);
Console.WriteLine(address.HouseId);
See Retrieving Property name from lambda expression for the implementation of GetPropertyInfo. It gets the PropertyInfo of the member specified in the lambda expression (and checks that it is indeed a property), which you can use to set the property in the CreateAddress method.
Apart from that, #Corak's suggestion is a valid one. Maybe you shouldn't use a property per address type, but use a Dictionary<AddressType, Guid?> property. That may or may not be viable depending on the class design and its intended usage.
You can use expression trees to simplify your problem:
public class AddressService
{
public Address CreateAddress(Expression<Func<Address, Guid?>> idPropertySelector)
{
// So you get the property info to later set it using reflection
MemberExpression propertyExpr = (MemberExpression)idPropertySelector.Body;
PropertyInfo property = (PropertyInfo)propertyExpr.Member;
// Then you create an instance of address...
Address address = new Address();
// and you set the property using reflection:
property.SetValue(address, (Guid?)Guid.NewGuid());
return address;
}
}
Now, who knows where in your code, this will work:
AddressService service = new AddressService();
Address address = service.CreateAddress(a => a.FlatId);
Guid? flatId = address.FlatId; // This will be already assigned!
You can add a property BuildingType BuildingType being a value of the enum BuildingType { House, Flat, SomeOtherBuildingType, YetAnotherThing } as suggested by Corak.
To make it simpler, you can create a parameterized constructor in Address class:
public Address(Guid? id,BuildingType type)
{
switch(type)
{
case BuildingType.House:
HouseId=id;
break;
case BuildingType.Flat:
FlatId=id;
break;
case BuildingType.SomeOtherBuildingType:
SomeOtherBuildingTypeId =id;
break;
default:
break;
}
}
This way it will be easier to extend.
Also, you need not to have so many methods. Only one CreateAddress() can be used to generate address of multiple types.

Refer to Self's Type inside a class

in my C# class, I want to refer to type of the class itself, is it possible?
my sample code:
in the line of
private static List<CRcpParmPropEle<CParam1, string>> ParmPropList;
I don't want to use "CParam1", I wish to use some general way (like "this") to refer to itself. because I have many classes like CParam1, everyone would need to refer to itself this way.
class CParam1
{
private double m_Prop1;
private static List<CRcpParmPropEle<CParam1, string>> ParmPropList;
public CParam1()
{
}
////-> I wish to replace Cparam1 to something like this
public static List<CRcpParmPropEle<CParam1, string>> getParmPropList()
{
if (ParmPropList == null)
{
ParmPropList.Add(new CRcpParmPropEle<CParam1, string>("Prop1", "BA", 0, false));
//-> I wish to replace Cparam1 to something like this
}
return ParmPropList;
}
public string Prop1
{
get
{
return m_Prop1.ToString();
}
set
{
m_Prop1 = -1;
double dW1;
if (double.TryParse(value, out dW1))
{
m_Prop1 = dW1;
}
}
}
public class CRcpParmPropEle<T,TProp>
{
public Func<T, TProp> getter;
public Action<T, TProp> setter;
public string PropName { get; set; }
public string ColPos { get; set; }
public int ColNum { get; set; }
public int RowNum { get; set; }
public bool ReadOnly { get; set; }
public CRcpParmPropEle(string strPropName, string strColPos, int nRowNum, bool bReadOnly)
{
PropName = strPropName;
ColPos = strColPos;
RowNum = nRowNum;
ReadOnly = bReadOnly;
var prop = typeof(T).GetProperty(PropName); //typeof(rcpObj).GetProperty(propName);
getter = (Func<T,TProp>)Delegate.CreateDelegate(typeof(Func<T,TProp>), prop.GetGetMethod());
setter = (Action<T,TProp>)Delegate.CreateDelegate(typeof(Action<T,TProp>), prop.GetSetMethod());
}
}
In general, no. There is no way to do this. Since in the contexts where this would typically be used, one is writing code specific to the type anyway, and since we are used to having to specify the type name for static members anyway, this doesn't seem like much of a hardship.
But, there are a couple of alternatives that could work in your scenario, both involving generics.
The first is to delegate the construction of the new object to a generic helper method:
public static List<CRcpParmPropEle<CParam1, string>> getParmPropList()
{
if (ParmPropList == null)
{
AddToList(ParmPropList, "Prop1", "BA", 0, false);
}
return ParmPropList;
}
private static void AddToList<T>(List<CRcpParmPropEle<T, string>> list, string s1, string s2, int i, bool f)
{
list.Add(new CRcpParmPropEle<T, string>(s1, s2, i, f));
}
In this way, the actual type is inferred from the type of the List<T> object being passed in, and so doesn't need to be restated. Of course, you don't get out of specifying the type somewhere. It just doesn't wind up at this particular call site.
Another option is to use a static helper class to implement the static functionality of your CParam1 class:
static class ParmPropClass<T>
{
private static List<CRcpParmPropEle<T, string>> ParmPropList;
public static List<CRcpParmPropEle<T, string>> getParmPropList()
{
if (ParmPropList == null)
{
ParmPropList.Add(new CRcpParmPropEle<T, string>("Prop1", "BA", 0, false));
}
return ParmPropList;
}
}
Then when you use the static members, you have to specify the type name as ParmPropClass<CParam1> (or whatever, depending on what you wind up naming the helper class). Again, you don't get out of specifying the type name somewhere, but the call site doesn't need to.
In fact, if you are doing this kind of pattern exactly in a number of locations, the generic helper type might be a better way to go, since then you don't have to copy/paste code all the time (a recipe for failing to fix some bug in all the places it was copied to).
There is no straight forward or easy to implement answer here. I'll give you three options but I don't think any of these would be easier than just changing all of the classes. If I had to do this right I would use a dependency injector. in the long run you will be better off and you'll be able to handle this stuff easier next time around. If I had to do it fast and desperate I would use reflection.
Option 1 - Reflection
You could assemble the List at runtime using reflection.
Look at this post for an example of creating a list at runtime with reflection.
Generic list by using reflection
This will make your code really nasty to maintain and you will have to use reflection throughout to manage the list. You would probably add more headaches in runtime errors and difficulty debugging than just changing it everywhere
Option 2 - Common Base Class
If you can make all the CPARAM1 type objects implement from a common base class CPARAMBASE you could define the list using the common base class.
private static List<CRcpParmPropEle<CParamBase, string>> ParmPropList;
Option 3 - Dependency Injection
This isn't something you can just cover in a SO answer but look at dependency injection.
You create an interface between all of the CPARAM type classes and then you inject a concrete type for based on what type it is being injected into.
[Inject]
private static List<CRcpParmPropEle<ICParam, string>> ParmPropList;
In your dependency Injection you could define that ICParam instance would be.
this.Bind<List<CRcpParmPropEle<ICParam, string>>>()
.To<List<CRcpParmPropEle<CParam1, string>>>()
.WhenInjectedInto(typeof(CParam1));
Look up Ninject and then Contextual Binding and http://www.ninject.org/wiki.html

Execute function kept in the attribute upon property change

I have a property with has an attribute, which in turn has Func<object, object>, I want that function to be executed (using the updated property's value as in T) upon the property change. What's the slickest way of doing so?
Note: I'm aware of the facts that Attributes are static and aren't designed to be executed upon their assignees change/invocaction. I just need to get it working as close as can to the prototype I've created.
Some code:
using System;
using System.Windows;
namespace AnnotatedBinding
{
public class AnnotatedPropertyAttribute: Attribute
{
// static
public AnnotatedPropertyAttribute(Func<object, object> evaluator)
{
Evaluator = evaluator;
}
public Func<object, object> Evaluator
{
get; private set;
}
}
public class Test
{
[AnnotatedProperty(Test.TestEvaluator)] // not compiling!, guess it's fixable by passing in a member info and then calling Reflection Invoke?
public string TestProperty
{
get; set;
}
public static Func<object, object> TestEvaluator = (x) => MessageBox.Show(x.ToString());
}
public class Shell
{
public void Run()
{
var test = new Test();
test.TestProperty = "blah";// I want my message box here
test.TestProperty = "blah";// and I don't want it here
}
}
}
Your attribute on the TestProperty does not compile because delegates are not allowed as attribute arguments. See this answer from Eric Lippert for details about which types are allowed.
Regarding a workaround using reflection: You could certainly specify the type owning the method, and the name of the method in the attribute since System.Type and string are valid attribute argument types. Something like this:
[AnnotatedProperty(typeof(Test), "TestEvaluator")]
public string TestProperty { get; set; }
However, this still won't do anything with the delegate when the property is set. Attributes are only metadata that you can read out during runtime using reflection (more specifically using MemberInfo.GetCustomAttributes(...)), analyse them and perform any operation based on the attribute values. This all needs to be done manually. Unfortunately, the .NET framework does not offer the functionality to automatically perform some operation based on the attributes that are applied to a member. This would make life a lot easier for property change notifications as well.
So you would have to implement the handling of the attributes manually. That means, implementing the get and set accessors, checking whether the attribute is applied to that property, determine the delegate that should be executed, and exeute it using reflection. Of course, that does not make sense because you would rather add a call to the method in the setter instead.
tl;dr:
Possible solution: You should have a look at PostSharp, a library supporting aspect-oriented programming in .NET. It can be used to inject boiler-plate code into methods or other members after compilation. It does this by analyzing your MSIL code and searching for so-called "aspects" (which are actually attributes, like yours). If found, it modifies the MSIL as specified by the attribute. You would have to derive your attribute from a PostSharp base attribute/aspect and then override the appropriate methods. In your case, you would have to derive from the LocationInterceptionAspect and then override the OnSetValue(...) method. In this method you would determine the delegate using the attribute arguments (as given above) and then call this using reflection. "Intercepting Properties and Fields" in the PostSharp documentation gives a very good introduction how to do this.
I think you would end up with something like this:
public class ExecuteDelegateOnPropertySetAspect : LocationInterceptionAspect
{
public ExecuteDelegateOnPropertySetAspect(Type methodOwner, string methodName, object[] arguments)
{
this.MethodOwner = methodOwner;
this.MethodName = methodName;
this.Arguments = arguments;
}
public Type MethodOwner { get; set; }
public string MethodName { get; set; }
public object[] Arguments { get; set; }
public override void OnSetValue(LocationInterceptionArgs args)
{
// get method with the specified name from the specified owner type
MethodInfo method = this.MethodOwner.GetMethod(this.MethodName);
// method must be static, otherwise we would need an instance to call it
if (method != null && method.IsStatic)
{
if (method.GetParameters().Length == this.Arguments.Length)
{
// call the method with the given arguments
method.Invoke(null, this.Arguments);
}
}
// execute the original setter code
args.ProceedSetValue();
}
}
And in your code you would apply this aspect to your properties:
public class Test
{
public static void TestMethod(string someMessage)
{
MessageBox.Show(someMessage);
}
[ExecuteDelegateOnPropertySetAspect(typeof(Test), "TestMethod", new object[] { "Hello world!" })]
public string TestProperty { get; set; }
}
Note that I omitted most of the error and null checking to keep it simple and short.
You seem to have misunderstood the concept of properties in C#.
The properties have a getter and setter function. They will automatically get executed when you set the property or get its value.
So all you need to do is to change the set function of your property to something like this:
public class Test
{
private string _testProperty;
private bool testPropertyIsSet = false;
public string TestProperty
{
get { return this._testProperty; }
set
{
_testProperty = value;
if (!testPropertyIsSet)
{
// Do something here when your property gets set for the first time
}
testPropertyIsSet = true;
}
}
}
Then call it:
public void Run()
{
var test = new Test();
test.TestProperty = "blah";
test.TestProperty = "blah2";
}

C# Custom Attribute code -> Look at the field that it was associated with

I have a C# class that is used in my custom DB ORM tools, called DbFieldAttribute.
I place it over my field, like so:
[DbField("User_Id")]
public int UserId{ get; set; }
Challenge: From my attributes Constructor code, get the FieldInfo of the field it is associated with the attribute. In the case above, it would give me the FieldInfo for UserId.
Any help would be great. Thanks.
Unfortunately, to the best of my knowledge, there is no way to accomplish what you are asking for.
But if it is not necessary that you get the PropertyInfo or the FieldInfo object inside your constructor, but instead you would be satisfied with it being passed to a method, then there is a possible solution.
First of all, your DbField class would need to be defined in the following way.
class DbField : Attribute
{
public DbField(string source) { }
public void GetInstance(PropertyInfo source)
{
Console.WriteLine(source.Name);
}
}
You would then need to define the following class which would get all the (in this case) properties marked with the DbField attribute, and pass them to the GetInstance(PropertyInfo) method.
class ActivateAttributes
{
public ActivateAttributes(object source)
{
source.GetType()
.GetProperties()
.Where(x => x.GetCustomAttributes().OfType<DbField>().Any())
.ToList()
.ForEach(x => (x.GetCustomAttributes().OfType<DbField>().First() as DbField).GetInstance(x));
}
}
The way you would trigger this process is inside an abstract class, which is defined as so.
abstract class AbstractDecoratedClass
{
public AbstractDecoratedClass()
{
new ActivateAttributes(this);
}
}
Now your target class, which has its properties decorated by DbField attributes, simply needs to derive from this class, so that you won't be bothered by the invocation inside the constructor.
class DecoratedClass : AbstractDecoratedClass
{
[DbField("User_Id")]
public int UserId { get; set; }
[DbField("User_Id2")]
public int UserId2 { get; set; }
}
You are now only left with testing the solution as shown here.
class Program
{
static void Main()
{
new DecoratedClass();
Console.Read();
}
}
The solution could not be solved directly, as #Mario pointed out, but here is the solution I ended up going with.
The key is to know that the attribute alone has no way of knowing this information, but at the time it is called it is reasonable to expect that the FieldInfo or PropertyInfo was also available.
My original problem was that my ORM code looked to an attribute to determine if a field/property related to a database field. Then, I had instances where the Prop/Field name in the class did not match up with the database for reasons of making it more logical to the Code/Db. In those cases I needed to pass in a field name to use instead of the actual field. I was hoping the attribute could do more of the work, or at least help make it more obvious for any future code that used it.
(I stripped out xml comments and extra code not relavant to this solution)
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DbFieldAttribute : Attribute
{
private string fieldName = "";
public DbFieldAttribute() { }
public DbFieldAttribute(string fieldName)
{
this.fieldName = fieldName;
}
public string FieldName(PropertyInfo pi)
{
if (this.fieldName != "") return this.fieldName;
else return pi.Name;
}
public string FieldName(FieldInfo fi)
{
if (this.fieldName != "") return this.fieldName;
else return fi.Name;
}
Now when my ORM code wants the field name, it has to pass in the field or property info related to that field. This means that what is needed, is now intrinsic in the attributes use, instead of needing to be derived in external code.

Categories