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

我可以检测是否传递了一个新对象作为参数吗?分享

时间:2023-04-10 17:56:53 C#

我可以检测是否给了一个新的对象作为参数吗?简短版本对于那些没有时间阅读我对以下问题的推理的人:有没有办法对方法的参数执行“仅限新对象”或“仅限现有对象”策略?Longversion有很多方法以对象作为参数,一个方法是否有一个对象“alltothem”并不重要。例如:varpeople=newList();人bob=newPerson("Bob");人。添加(鲍勃);people.Add(newPerson("Larry"));这里的List.Add方法使用“现在有一个”人(Bob)和一个“新”人(Larry),列表包含两个项目。Bob可以是bob或people[0]。Larry可以作为people[1]访问,如果需要,可以缓存larry(或其他)并在以后访问。好的但有时确实不应该将方法传递给新对象。以数组为例。排序为例。以下没有多大意义:Array.Sort(newint[]{5,6,3,7,2,1});上面的所有代码都是采用一个新数组,对其进行排序,然后忘记它(因为它的引用计数在Array.Sort退出后变为零,所以如果我没记错的话,排序后的数组将被垃圾收集)。所以Array.Sort期望一个“现有”数组作为它的参数。可以想象其他方法可能期望一个“新”对象(尽管我通常认为这样的期望是设计错误)。一个不完美的例子是:DataTablefirstTable=myDataSet.Tables["FirstTable"];DataTablesecondTable=myDataSet.Tables["SecondTable"];firstTable.Rows.Add(secondTable.Rows[0]);正如我所说,这不是一个很好的例子,因为DataRowCollection.Add实际上并不期望一个新的DataRow;但它确实需要一个不属于DataTable的DataRow。所以上面代码的最后一行不起作用;它需要是:firstTable.ImportRow(secondTable.Rows[0]);无论如何,这是我的问题的很多设置,即:通过一些我不知道的自定义属性或在方法本身内(可能通过反射,虽然我可能会避免它,即使它可用)?如果没有,欢迎任何有关如何实现这一目标的有趣想法。例如,我想如果有某种方法可以获取给定对象的GC引用计数,您当然可以立即告诉方法的开头是否已收到新对象(假设您正在处理引用类型)-那是唯一与这个问题场景相关的场景。编辑:版本越来越长。好吧,假设我有一些方法可以选择接受TextWriter来输出它的进度或者你有什么:staticvoidTryDoSomething(TextWriteroutput){//dosomething...if(output!=null)output.WriteLine("Did某物...”);//做点别的事...if(output!=null)output.WriteLine("Didsomethingelse...");//等等if(output!=null)//我是否调用output.Close()?}staticvoidTryDoSomething(){TryDoSomething(null);现在,让我们考虑调用此方法的两种不同方式:stringpath=GetFilePath();使用(StreamWriterwriter=newStreamWriter(path)){TryDoSomething(writer);//用writer做更多的事情}或者:TryDoSomething(newStreamWriter(path));嗯...看起来这会引起问题,不是吗?我构建了一个实现IDisposable的StreamWriter,但TryDoSomething不假定知道它是否具有对其输出参数的独占访问权。因此,对象要么过早放置(在第一种情况下),要么根本不放置(在第二种情况下)。我并不是说它一定是一个伟大的设计。也许JoshStodola是对的,这从一开始就是个坏主意。无论如何,我问这个问题主要是因为我很好奇这样的事情是否可能。看起来答案是:不是真的。不,基本上。两者之间真的没有区别:varx=new...;福(x);和富(新...);事实上,有时出于调试目的,您可能会在两者之间切换。请注意,在DataRow/DataTable示例中,有一个替代方案-DataRow可以知道其父级作为其状态的一部分。这与“新”或不“新”不同——例如,您可以进行“分离”操作。根据对象的真实硬状态来定义条件比使用诸如“新”之类的粗略术语更有意义。是的,有办法做到这一点。有点儿。如果将参数设为ref参数,则必须将现有变量作为参数传递。你不能做这样的事情:DoSomething(refnewCustomer());如果这样做,您将收到错误消息“reforoutparametermustbeanassignablevariable”。当然,使用ref有其他含义。但如果您是方法的编写者,则无需担心它们。只要不在方法中重新分配ref参数,是否使用ref都没有任何区别。我并不是说它一定是好的风格。你不应该使用ref或out除非你真的,真的需要并且没有其他方法可以做你正在做的事情。但是使用ref将使您想要做的事情起作用。不可以。如果出于某种原因您需要这样做,则说明您的代码架构不正确。简短回答-否在绝大多数情况下,我通常发现上面列出的问题并不重要。当他们这样做时,您重载该方法,以便您可以接受其他东西作为参数,而不是您担心共享的对象。//例如,创建一个允许您执行此操作的方法:people.Add("Larry");//而不是这个:people.Add(newPerson("Larry"));//新方法可能看起来有点像这样:publicvoidAdd(stringname){Personperson=newPerson(name);这个。添加(人);//如有必要,此方法可以是私有的}我可以弄清楚如何执行此操作,但我绝对不会推荐这样做。只是为了争论。对象成为“新”对象意味着什么?这意味着只有一个引用使它保持活动状态。“现有”对象将有多个引用。记住这一点,看看下面的代码:Console.WriteLine(IsExistingObject(o));Console.WriteLine(IsExistingObject(新对象()));o.ToString();//只是模拟o的进一步使用。如果我们不这样做,在发布版本中,o将由IsExistingObject中的GC.Collect调用收集。(不在调试版本中)}publicstaticboolIsExistingObject(objecto){varoRef=newWeakReference(o);#ifDEBUGo=null;//在Debug中,我们需要将o设置为null。这在发布版本中不是必需的。#endifGC.Collect();GC.WaitForPendingFinalizers();返回oRef.IsAlive;}}这会在第一行打印True,在第二行打印False。但是,请不要在您的代码中使用它。让我将您的问题重写为一个较短的问题。在我的方法中,以一个对象作为参数,有没有办法知道这个对象是否会在我的方法之外使用?简而言之:不。在这一点上让我冒昧地发表一个意见:不应该有任何这样的机制。这使整个地方的方法调用变得复杂。如果有一种方法可以告诉我在方法调用中是否实际使用了我提供的对象,那么作为方法的开发人员,这是一个信号,需要考虑到这一点。基本上,您会看到这种类型的代码(假设,因为它不可用/不支持:)if(ReferenceCount(obj)==1)return;//唯一的参考是我们所拥有的我的观点是:如果调用您的方法的代码不会将该对象用于任何事情,并且除了修改对象之外没有任何副作用,那么该代码不应该存在。就像代码看起来像这样:1+2;这段代码有什么作用?好吧,根据C/C++编译器,它可能会编译为计算结果为1+2的内容。但是结果存储在哪里呢?你用它来做什么?不?那么为什么源代码的代码部分开始呢?当然,你可以说代码实际上是a+b;,为了确保a+b的评估不会抛出指示溢出的异常,但这种情况非常罕见,它的特殊情况只会掩盖真正的问题,只需将它分配给a就可以很容易地修复临时变量。无论如何,对于任何编程语言和/或运行时和/或环境中的任何特性,如果一个特性不可用,其不可用的原因是:所有这些都需要在应用程序Y的版本X中显示一个功能,无论是C#4.0还是MSWorks7.0。不,没有办法知道。传入的所有内容都是对象引用。无论是就地“新”,还是从数组派生,所讨论的方法都无法知道传入的参数是如何和/或在何处实例化的。在调用函数/方法之前知道传递给函数(或方法)的对象是否已创建的一种方法是对象是否具有使用从系统函数传递的时间戳初始化的属性;这样,看那个属性,就有可能解决问题。坦率地说,我不会使用这种方法,因为另一种解决方案是使用一个对象属性,该属性设置为对象创建者的值,并且该对象属性设置为与该对象的所有方法不同的值。在这种情况下,问题在于忘记添加代码来更改每个方法中的属性。我再次问自己“我真的需要这样做吗?”。作为一种可能的部分解决方案,如果你只想让一个对象被一个方法使用,那么你可以看看单例。这样,如果该方法已经存在,则该方法无法创建另一个实例。C#学习教程就是这样:我可以检测是否将新对象作为参数传递了吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: