如何为.NET属性创建委托?我正在尝试创建一个委托(作为测试):PublicOverridableReadOnlyPropertyPropertyName()AsString我的直觉尝试是像这样声明委托:PublicDelegateFunctionTest()AsString并像这样实例化它:Dimt作为测试=AddressOfe。PropertyName但这会引发错误:方法“PublicOverridableReadOnlyPropertyPropertyName()AsString”没有与委托“DelegateFunctionTest()AsString”兼容的签名。因为我正在处理一个属性,所以我尝试了这个:PublicDelegatePropertyTest()AsString但这会引发编译器错误。所以问题是,我如何代表财产?请参阅此链接:http://peisker.net/dotnet/propertydelegates.htm使用AddressOf解决问题-如果您在编译时知道prop-name,则可以(至少在C#中)使用anon-method/lambda:测试t=delegate{returne.PropertyName;};//C#2.0测试t=()=>e.PropertyName;//C#3.0我不是VB专家,但reflector声称这与:DimtAsTest=FunctionWouldReturne.PropertyNameEndFunctionworklikethat?原始答案:您可以使用Delegate.CreateDelegate为属性创建委托;这对任何类型的实例都是开放的,对单个实例是固定的——并且可以用于getter或setter;我将在C#中举一个例子......使用System;使用System.Reflection;classFoo{publicstringBar{get;放;}}classProgram{staticvoidMain(){PropertyInfoprop=typeof(Foo).GetProperty("Bar");foofoo=newFoo();//创建一个开放的“getter”委托FuncgetForAnyFoo=(Func)Delegate.CreateDelegate(typeof(Func),null,prop.GetGetMethod());FuncgetForFixedFoo=(Func)Delegate.CreateDelegate(typeof(Func),foo,prop.GetGetMethod());动作setForAnyFoo=(动作)委托。创建委托e(typeof(Action),null,prop.GetSetMethod());动作setForFixedFoo=(Action)Delegate.CreateDelegate(typeof(Action),foo,prop.GetSetMethod());setForAnyFoo(foo,"abc");控制台.WriteLine(getForAnyFoo(foo));setForFixedFoo("def");Console.WriteLine(getForFixedFoo());我刚刚创建了一个性能相当不错的助手:http://thibaud60.blogspot.com/2010/10/fast-property-accessor-without-dynamic.html它不使用IL/Emit方法而且速度非常快!由oscilatingcretin编辑2015/10/23源代码包含一些大小写问题,必须删除特殊的=""在链接失效之前,我想我应该发布一个清理版本的源代码以便更容易复制意大利面条,以及如何使用它的例子。修改来源usingSystem;使用System.Collections.Concurrent;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用System.Reflection;命名空间Tools.Reflection{公共接口IPropertyAccessor{PropertyInfoPropertyInfo{get;}objectGetValue(对象源);voidSetValue(对象源,对象值);}publicstaticclassPropertyInfoHelper{privatestaticConcurrentDictionary_cache=newConcurrentDictionary();publicstaticIPropertyAccessorGetAccessor(PropertyInfopropertyInfo){IPropertyAccessorresult=null;if(!_cache.TryGetValue(propertyInfo,outresult)){result=CreateAccessor(propertyInfo);_cache.TryAdd(propertyInfo,结果);;}返回结果;}publicstaticIPropertyAccessorCreateAccessor(PropertyInfoPropertyInfo){varGenType=typeof(PropertyWrapper).MakeGenericType(PropertyInfo.DeclaringType,PropertyInfo.PropertyType);返回(IPropertyAccessor)Activator.CreateInstance(GenType,Propert信息);}}内部类PropertyWrapper:IPropertyAccessor其中TObject:类{privateFuncGetter;私人行动二传手;publicPropertyWrapper(PropertyInfoPropertyInfo){this.PropertyInfo=PropertyInfo;MethodInfoGetterInfo=PropertyInfo.GetGetMethod(true);MethodInfoSetterInfo=PropertyInfo.GetSetMethod(true);Getter=(Func)Delegate.CreateDelegate(typeof(Func),GetterInfo);Setter=(Action)Delegate.CreateDelegate(typeof(Action),SetterInfo);}objectIPropertyAccessor.GetValue(objectsource){returnGetter(sourceasTObject);}voidIPropertyAccessor.SetValue(objectsource,objectvalue){Setter(sourceasTObject,(TValue)value);}publicPropertyInfoPropertyInfo{得到;私有集;}}}像这样使用它:publicclassMyClass{publicintId{get;放;}publicstringFirstName{get;放;}publicstringLastName{get;放;}publicintAge{得到;放;}}MyClasse=newMyClass();IPropertyAccessor[]访问器=e.GetType().GetProperties().Select(pi=>PropertyInfoHelper.CreateAccessor(pi)).ToArray();foreach(varAccessorinAccessors){Typept=Accessor.PropertyInfo.PropertyType;如果(pt==typeof(string))Accessor.SetValue(e,Guid.NewGuid().ToString("n").Substring(0,9));elseif(pt==typeof(int))Accessor.SetValue(e,newRandom().Next(0,int.MaxValue));Console.WriteLine(string.Format("{0}:{1}",Accessor.PropertyInfo.Name,Accessor.GetValue(e)));}这是MarcGravell的C#/NET2.0版本的回复:usingSystem;使用System.Reflection;类程序{私有委托voidSetValue(T值);私人代表TGetValue();私有类Foo{私有字符串_bar;publicstringBar{get{return_bar;}设置{_bar=值;}}}staticvoidMain(){Foofoo=newFoo();类型type=typeof(Foo);PropertyInfo属性=type.GetProperty("Bar");//setterMethodInfomethodInfo=property.GetSetMethod();SetValuesetValue=(SetValue)Delegate.CreateDelegate(typeof(SetValue),foo,methodInfo);设置值(“abc”);//gettermethodInfo=property.GetGetMethod();GetValuegetValue=(GetValue)Delegate.CreateDelegate(typeof(GetValue),foo,methodInfo);字符串myValue=getValue();//输出结果Console.WriteLine(myValue);}}一样,'Delegate.CreateDelegate'是这个例子的基础。这是个好主意Testt=()=>e.PropertyName;//C#3.0但要小心你是否在做这样的事情:List>funcs=newList>();foreach(vareinCollection)funcs.Add(newFunc(()=>e.Property));调用:foreach(varfinfuncs)f();将始终返回集合中最后一个对象的属性值在这种情况下,您应该调用方法:foreach(vareinCollection)funcs.Add(newFunc(e.GetPropValue));这是一个C#示例,但对所有类型都相同:首先创建接口(委托)。请记住,附加到委托的方法必须返回与委托声明相同的类型并采用相同的参数。不要在与事件相同的范围内定义委托。公共委托voiddelgJournalBaseModified();基于委托创建事件:publicstaticclassJournalBase{publicstaticeventdelgJournalBaseModifiedevntJournalModified;};定义一个可以绑定到与委托具有相同接口的事件的方法。voidUpdateEntryList(){}将方法绑定到事件。当触发事件时调用此方法。您可以将各种方法绑定到事件。我不知道极限。这可能是疯狂的事情。JournalBase.evntJournalModified+=newdelgJournalBaseModified(UpdateEntryList);这里发生的是这个方法被添加为你的事件的回调。当事件被触发时,您的方法将被调用。接下来,我们创建一个在调用时触发事件的方法:}};然后你只需调用方法-JournalBase_Modified()-在你的代码中的某个地方,与你的事件相关的所有方法也将被一个接一个地调用。VB版:以上是C#学习教程:如何为.NET属性创建委托?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——DimpropAsPropertyInfo=GetType(foo).GetProperty("bar")Dimfoo1AsNewfooDimgetForAnyFooAsFunc(Offoo,String)=TryCast([Delegate].CreateDelegate(GetType(Func(Offoo,String)),Nothing,prop.GetGetMethod()),Func(Offoo,String))DimsetForAnyFoo复制代码作为Action(Offoo,String)=TryCast([Delegate].CreateDelegate(GetType(Action(Offoo,String)),Nothing,prop.GetSetMethod()),Action(Offoo,String))DimgetForFixedFooAsFunc(OfString)=TryCast([Delegate].CreateDelegate(GetType(Func(OfString)),foo1,prop.GetGetMethod()),Func(OfString))DimsetForFixedFooAsAction(OfString)=TryCast([Delegate].CreateDelegate(GetType(Action(OfString)),foo1,prop.GetSetMethod()),Action(OfString))setForAnyFoo(foo1,"abc")Debug.WriteLine(getForAnyFoo(foo1))setForFixedFoo("def")Debug.WriteLine(getForFixedFoo())本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
