我可以检测是否我已经被赋予了新的对象作为参数? [英] Can I detect whether I've been given a new object as a parameter?

查看:111
本文介绍了我可以检测是否我已经被赋予了新的对象作为参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于那些没有时间阅读我的推理下面这个问题谁:

For those who don't have the time to read my reasoning for this question below:

有什么办法强制执行仅新对象或仅现有对象的政策,方法的参数

有大量的内搭对象作为参数的方法,并无所谓的方法是否有对象一切以自己与否。例如:

There are plenty of methods which take objects as parameters, and it doesn't matter whether the method has the object "all to itself" or not. For instance:

var people = new List<Person>();

Person bob = new Person("Bob");

people.Add(bob);
people.Add(new Person("Larry"));

下面的名单,其中,人物&GT;。新增方法,采取了现有(BOB)以及作为一个新(拉里),并且该列表包含两个项目。 Bob可以进行访问,无论是鲍勃·人[0] 。拉里也可以访问人[1] 和,如果需要的话,缓存和访问为拉里(或其他)之后

Here the List<Person>.Add method has taken an "existing" Person (Bob) as well as a "new" Person (Larry), and the list contains both items. Bob can be accessed as either bob or people[0]. Larry can be accessed as people[1] and, if desired, cached and accessed as larry (or whatever) thereafter.

OK,挺好的。但有时一个方法真正的不应该的传递一个新的对象。举个例子来说,的Array.Sort&LT; T&GT; 。以下不作一大堆的道理:

OK, fine. But sometimes a method really shouldn't be passed a new object. Take, for example, Array.Sort<T>. The following doesn't make a whole lot of sense:

Array.Sort<int>(new int[] {5, 6, 3, 7, 2, 1});

以上所有code确实是需要一个新的数组,排序它,然后忘记它(因为它的引用计数后的的Array.Sort&LT达到零; INT&GT; 退出,有序数组会因此被垃圾收集,如果我没有记错)。因此,的Array.Sort&LT; T&GT; 希望的一个现有的数组作为它的参数

All the above code does is take a new array, sort it, and then forget it (as its reference count reaches zero after Array.Sort<int> exits and the sorted array will therefore be garbage collected, if I'm not mistaken). So Array.Sort<T> expects an "existing" array as its argument.

有令人信服的其他方法可能的期望的新的对象(虽然我一般都认为,能有这样的期待将是一个设计错误)。一个完美的例子是这样的:

There are conceivably other methods which may expect "new" objects (though I would generally think that to have such an expectation would be a design mistake). An imperfect example would be this:

DataTable firstTable = myDataSet.Tables["FirstTable"];
DataTable secondTable = myDataSet.Tables["SecondTable"];

firstTable.Rows.Add(secondTable.Rows[0]);

正如我所说的,这不是一个很好的例子,因为 DataRowCollection.Add 实际上并没有指望的的DataRow ,完全;但它的确实的期望的DataRow 尚不属于数据表。因此,在code中的最后一行上面将无法正常工作;它需要:

As I said, this isn't a great example, since DataRowCollection.Add doesn't actually expect a new DataRow, exactly; but it does expect a DataRow that doesn't already belong to a DataTable. So the last line in the code above won't work; it needs to be:

firstTable.ImportRow(secondTable.Rows[0]);

无论如何,这是一个很大的设置为我的问题,那就是:有没有什么办法来执行新对象仅或一个方法的参数唯一存在的对象的政策,无论是在它的定义(也许是一些自定义属性,我不知道)或方法本身(可能是反射,但我可能会回避这个,即使它是可用)内?

Anyway, this is a lot of setup for my question, which is: is there any way to enforce a policy of "new objects only" or "existing objects only" for a method's parameters, either in its definition (perhaps by some custom attributes I'm not aware of) or within the method itself (perhaps by reflection, though I'd probably shy away from this even if it were available)?

如果没有,什么有趣的想法,怎么可能做到这一点会更受欢迎。比如我想,如果有办法让GC的引用计数给定对象,你可以告诉马上在方法开始你是否已经收到一个新的对象,或没有(假设你正在处理的引用类型当然, - 这是唯一的方案到这个问题是不相干)

If not, any interesting ideas as to how to possibly accomplish this would be more than welcome. For instance I suppose if there were some way to get the GC's reference count for a given object, you could tell right away at the start of a method whether you've received a new object or not (assuming you're dealing with reference types, of course--which is the only scenario to which this question is relevant anyway).


修改

更长的版本变长。

好吧,假设我有我要有选择性地接受的TextWriter 来输出其进展或某些方法是什么 - 有 - 你:

All right, suppose I have some method that I want to optionally accept a TextWriter to output its progress or what-have-you:

static void TryDoSomething(TextWriter output) {
    // do something...
    if (output != null)
        output.WriteLine("Did something...");

    // do something else...
    if (output != null)
        output.WriteLine("Did something else...");

    // etc. etc.

    if (output != null)
        // do I call output.Close() or not?
}

static void TryDoSomething() {
    TryDoSomething(null);
}

现在,让我们考虑两种不同的方式,我可以调用这个方法:

Now, let's consider two different ways I could call this method:

string path = GetFilePath();
using (StreamWriter writer = new StreamWriter(path)) {
    TryDoSomething(writer);

    // do more things with writer
}

TryDoSomething(new StreamWriter(path));

嗯...这似乎这带来一个问题,不是吗?我已经构建了一个的StreamWriter ,它实现的IDisposable ,而 TryDoSomething 不会presume知道它是否具有独占访问其<$​​ C $ C>输出参数与否。所以对象既被布置prematurely(在第一种情况),或者不获取布置在所有(在第二种情况下)。

Hmm... it would seem that this poses a problem, doesn't it? I've constructed a StreamWriter, which implements IDisposable, but TryDoSomething isn't going to presume to know whether it has exclusive access to its output argument or not. So the object either gets disposed prematurely (in the first case), or doesn't get disposed at all (in the second case).

我并不是说这将是一个伟大的设计,未必。也许乔希斯托多拉是正确的,这是从一开始就只是一个坏主意。总之,我问的问题,主要是因为我只是好奇,如果这样的事情是的可能的。貌似答案是:不是真的

I'm not saying this would be a great design, necessarily. Perhaps Josh Stodola is right and this is just a bad idea from the start. Anyway, I asked the question mainly because I was just curious if such a thing were possible. Looks like the answer is: not really.

推荐答案

没有,基本上是这样。

确实没有区别:

var x = new ...;
Foo(x);

Foo(new ...);

确实有时候你可能会在两者之间转换进行调试。

and indeed sometimes you might convert between the two for debugging purposes.

请注意,在的DataRow / 数据表例如,有另一种方法,但 - 这DataRow中能的知道作为其状态的一部分的母公司。这是不一样的事情为新的或不 - 你可以有一个分离的操作为例。限定条件中的对象的真正硬和快速的状态来使得比羊毛术语,如新

Note that in the DataRow/DataTable example, there's an alternative approach though - that DataRow can know its parent as part of its state. That's not the same thing as being "new" or not - you could have a "detach" operation for example. Defining conditions in terms of the genuine hard-and-fast state of the object makes a lot more sense than woolly terms such as "new".

这篇关于我可以检测是否我已经被赋予了新的对象作为参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆