当前位置: 首页 > 编程语言 > C#

轻松创建C#可索引属性分享

时间:2023-04-10 15:08:19 C#

轻松创建C#可索引属性在C#中,我发现索引属性非常有用。例如:varmyObj=newMyClass();myObj[42]="你好";Console.WriteLine(myObj[42]);但据我所知,本身支持索引的字段没有语法糖(如果我错了请指正)。例如:varmyObj=newMyClass();myObj.field[42]="你好";Console.WriteLine(myObj.field[42]);我需要这个的原因是我已经在我的类上使用了索引属性,但是我有GetNumX()、GetX()和SetX()函数如下:publicintNumTargetSlots{get{return_Maker.NumRefs;}}publicReferenceTargetGetTarget(intn){returnReferenceTarget.Create(_Maker.GetReference(n));}publicvoidSetTarget(intn,ReferenceTargetrt){_Maker.ReplaceReference(n,rt._Target,true);您可能会发现将它们公开为可索引的字段属性更有意义。每次我想要语法糖时,我都可以编写一个自定义类来执行此操作,但所有样板代码似乎都是不必要的。因此,我编写了一个自定义类来封装样板文件,以便轻松创建可索引的属性。这样我就可以像这样添加一个新属性:}}这个新的IndexedProperty类的代码如下:publicclassIndexedProperty{ActionsetAction;函数获取函数;publicIndexedProperty(FuncgetFunc,ActionsetAction){this.getFunc=getFunc;this.setAction=setAction;}publicValueTthis[IndexTi]{get{returngetFunc(i);}set{setAction(i,value);所以我的问题是:有没有更好的方法来做这一切?具体来说,在C#中是否有更惯用的方法来创建可索引的字段属性,如果没有,我该如何改进我的IndexedProperty类?编辑:经过进一步研究,JonSkeet称其为“命名索引器”。嗯,最简单的方法是让属性返回一个实现IList的对象。请记住,仅仅因为它实现了IList并不意味着它本身就是一个集合,只是它实现了某些方法。从技术上讲,这不是使用StackOverflow的正确方法,但我发现您的想法非常有用,因此我对其进行了扩展。我认为,如果我发布我的想法以及如何使用它的示例,将会节省人们的时间。首先,我需要能够支持get-only和set-only属性,所以我为这些场景编写了略有不同的代码:get和set(非常小的更改):publicclassIndexedProperty{readonlyActionSetAction;只读函数GetFunc;publicIndexedProperty(FuncgetFunc,ActionsetAction){this.GetFunc=getFunc;this.SetAction=setAction;}publicTValuethis[TIndexi]{get{returnGetFunc(i);}set{SetAction(i,value);}}}只获取:publicclassReadOnlyIndexedProperty{readonlyFuncGetFunc;publicReadOnlyIndexedProperty(FuncgetFunc){this.GetFunc=getFunc;}publicTValuethis[TIndexi]{get{returnGetFunc(i);}}}只设置:publicclassWriteOnlyIndexedProperty{readonlyActionSetAction;publicWriteOnlyIndexedProperty(ActionsetAction){this.SetAction=setAction;}publicTValuethis[TIndexi]{set{SetAction(i,value);}}}示例这是一个简单的用法示例。我继承了Collection并创建了一个命名索引器,就像JonSkeet所说的那样。这个例子太简单了,不实用:}}privateTGetIndex(intindex){returnthis[index];}privatevoidSetIndex(intindex,Tvalue){this[index]=value;}}ExampleCollectionintheWild这个仓促构建的单元测试显示了当ExampleCollection在项目中时它的样子:MyExample.Add("a");MyExample.Add("b");Assert.IsTrue(MyExample.ExampleProperty[0]=="a");Assert.IsTrue(MyExample.ExampleProperty[1]=="b");MyExample.ExampleProperty[0]="c";Assert.IsTrue(MyExample.ExampleProperty[0]=="c");最后,如果你想使用Forget和only-only版本,它看起来像这样:}}或者:publicWriteOnlyIndexedPropertyExampleProperty{get{returnnewWriteOnlyIndexedProperty(SetIndex);在这两种情况下,结果的工作方式与您期望的get/only-only属性相同,我认为您发布的设计是可行的方法,我将定义一个接口的一个区别:我]{得到;放;对于常见情况,我会使用您在原始问题中提出的类(它将实现此接口)。如果基类库为我们提供了一个合适的接口就好了,但它没有。在这里返回一个IList是一种变态。这没有回答您的问题,但有趣的是CIL支持像您描述的那样创建属性——某些语言(例如F#)也允许您以这种方式定义它们。C#中的this[]索引器只是其中一个的特定实例,在您构建应用程序时将其重命名为Item。C#编译器只知道如何读取它,所以如果你在F#库中编写一个名为Target的“命名索引器”,并尝试在C#中使用它,你可以访问该属性的唯一方法是通过...get_Target(int)和voidset_Target(int,...)方法。糟透了。为什么不让你的类inheritIList然后你可以使用索引并添加你自己的属性。虽然您仍然可以使用添加和删除功能,但不要使用它们。另外,您可能会发现让它们上路更有用。有关列表和数组的更多信息,请查看:使用数组和列表哪个更好?编辑:MSDN上有一篇关于您可能想要查看的索引属性的文章。看起来并不复杂,只是乏味。http://msdn.microsoft.com/en-us/library/aa288464(VS.71).aspx还有另一种创建替代Add方法的选项,但根据对象的类型,add方法可能并不总是叫。在这里解释一下:HowtooverrideList'sAddmethodinC#?编辑2:类似于第一篇文章为什么你的类中没有隐藏列表对象,然后创建你自己的方法来获取数据。这样添加和删除是不可见的,并且列表已经被索引。另外,“命名索引器”是什么意思,您正在寻找row["My_Column_Name"]的等价物。我发现这篇MSDN文章可能很有用,因为它似乎展示了实现此属性的基本方法。http://msdn.microsoft.com/en-us/library/146h6tk5.aspxclassTest{私有列表索引;publicTthis[字符串名称]{get;放;}publicTthis[inti]{get{returnindex[i];}设置{索引[i]=值;}}}经过一些研究,我想出了一个稍微不同的解决方案,它更适合我的需要。这个例子有点编造,但它确实满足了我的需要。用法:MyClassMC=newMyClass();intx=MC.IntProperty[5];以及使其工作的代码:publicclassMyClass{publicreadonlyIntIndexingIntProperty;publicMyClass(){IntProperty=newIntIndexing(this);}privateintGetInt(intindex){switch(index){案例1:返回56;情况2:返回47;情况3:返回88;案例4:返回12;案例5:返回32;默认值:返回-1;}publicclassIntIndexing{privateMyClassMC;内部IntIndexing(MyClassmc){MC=mc;}publicintthis[intindex]{get{returnMC.GetInt(index);}}}}尝试显式实现接口,正如回复中第二种方式所建议的那样:NamedindexedpropertiesinC#?以上就是C#学习教程:轻松创建支持C#索引共享的属性。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢