有没有一种方法可以存储对对象引用的引用?

时间:2018-08-28 16:52:37

标签: c#

public class Program
{
    public static void Main()
    {
        Test[] tests = new Test[5];
        tests[0] = new Test(){Name = "A"};

        var consumer = new Consumer();
        consumer.test = tests[0];

        Console.WriteLine(consumer.test.Name);   //Prints A
        tests[0] = new Test(){Name = "B"};
        Console.WriteLine(consumer.test.Name);   //Would like this to point to new object and print B
    }
}

class Test
{
    public string Name {get; set;}
}

class Consumer
{
    public Test test {get; set;}
}

我想知道是否有可能直接在c#中实现这种功能。换句话说,Consumer.test可以指向位于tests [0]中的任何Test实例,以便当数组元素值更改时,我仍然可以访问该新值。或者换一种说法,是否可以保留对对象实例的引用的引用?我知道一种解决方法是仅创建一个容器类来保存对Test对象的引用,并将其传递给我,但是我再次想知道是否可以直接执行此操作。

2 个答案:

答案 0 :(得分:1)

您可以通过创建自己的委托包装器类来实现这一目标

<?php
/*
Template Name: DT - Listagem
*/
get_header();
doo_glossary('tvshows');
global $user_ID;
$dt = isset( $_GET['get'] ) ? $_GET['get'] : null;
$admin = isset( $_GET['admin'] ) ? $_GET['admin'] : null;
echo '<div class="module"><div class="content">';
get_template_part('inc/parts/modules/featured-post-tvshows');
echo '<div id="archive-content" class="animation-2 items calendar">';
// Sort alphabetically
global $wp_query;
$pages = $wp_query->max_num_pages;
$first_char = $_GET['letter'];
$postids=$wpdb->get_col($wpdb->prepare("
SELECT      ID
FROM        $wpdb->posts
WHERE       SUBSTR($wpdb->posts.post_title,1,1) = %s
ORDER BY    $wpdb->posts.post_title",$first_char)); 

if (isset( $_GET['letter'] )) {
query_posts(array(
    'post__in'      => $postids,
    'posts_per_page' => $pages,
    'caller_get_posts'=> 1,
    'paged' => $paged,
    'post_status'   => 'publish',
    'post_type'     => array('list'),
    'meta_key'      => 'medium_type',
    'meta_value'    => 'Listing',
    'order'         => 'ASC',
    'orderby'       => 'title'
)); } else {

query_posts(array(
    'posts_per_page' => $pages,
    'paged' => $paged,
    'post_type'     => array('list'),
    'meta_key'      => 'medium_type',
    'meta_value'    => 'Listing',
    'order'         => 'ASC',
    'orderby'       => 'title'
));

}
if (have_posts()) {
echo '<header><h1>'. __d('Listagem'). '</h1><span>Total ('.$wp_query->found_posts . ')</span></header>';
    while (have_posts()) {
        the_post();
        get_template_part('inc/parts/item');
    }
}else { echo '<header><h1>'. __d('Listagem'). '</h1><span>Total ('.$wp_query->found_posts . ')</span></header>';
echo '<div class="wp-content">
<blockquote><p>At the moment this session is without any content, soon it will be activated.</p></blockquote>
</div>'; }
echo '</div>';
if ( function_exists("pagination") ) {
    pagination();
}
echo '</div>';
get_template_part('inc/parts/sidebar');
echo '</div>';
get_footer();

将您的Consumer类修改为以下内容(添加构造函数并修改数据类型以利用委托包装器:

class MyRef<T> 
{
    private Func<T> getter;

    public MyRef(Func<T> getter)
    {
        this.getter = getter;
    }

    public T Value
    {
        get { return getter(); }
    }
}

,您在Main的消费者声明变为

class Consumer
{
    public MyRef<Test> test { get; set; }

    public Consumer(MyRef<Test> t){
        test = t;   
    }
}

您需要将来自消费者的呼叫更新为:

var consumer = new Consumer(new MyRef<Test>(() => tests[0]));

这里是DotNetFiddle

答案 1 :(得分:0)

我之前已经做过,但是在受限场景中。在大多数情况下,我最终都进行了重构以避免避免过多的间接调用,因为这种需求通常可能是不良设计的征兆。

您可以创建一个通用的Reference类,并保留对该类的引用而不是基础对象。如果执行此操作,则可能需要将IReference接口传递给“读取侧”或使用者,并将IChangeReference传递给“写入侧”,以便引用的内容可以被操纵。

public interface IReference<T>
{
    T Value { get;
}

public interface IChangeReference<T>
{
    void SetValue(T value);
}

public class Reference<T>: IReference<T>, IChangeReference<T>
{
    public Reference(T value) => Value = value;

    public T Value { get; private set; }

    public void SetValue(T value) => Value = value;
}

public class SomeConsumer
{
    private IReference<string> someField;
    ...
}