使用动态类型创建通用对象

问题描述 投票:0回答:1

我在C#中遇到泛型类型的问题。这是我的最小客户:

using Castle.DynamicProxy;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;

namespace WebProxyClientTester
{


    public class LiveResultPromise<R, L>
    {
        private Task<R> result;
        private IObservable<L> notification;

        public LiveResultPromise(Task<R> result, IObservable<L> notification)
        {
            this.result = result;
            this.notification = notification;
        }

        public Task<R> Result { get => result; set => result = value; }
        public IObservable<L> Notification { get => notification; set => notification = value; }
    }

    public class UserContact
    {
        public UserContact()
        {

        }
    }

    public class User
    {
        public User()
        {

        }
    }

    public class AddressBook
    {
        public AddressBook()
        {

        }
    }

    class Response<T>
    {
        private int id;
        private T result;
        private object error;

        public int Id { get => id; set => id = value; }
        public T Result { get => result; set => result = value; }
        public object Error { get => error; set => error = value; }
    }

    public interface MyInterface
    {
        LiveResultPromise<UserContact, UserContact> getUserContact(String username);
        LiveResultPromise<User, User> getUsers();
        LiveResultPromise<AddressBook, AddressBook> getAddressBook();
    }


    class Client
    {
        Subject<Response<dynamic>> wsResponse = new Subject<Response<dynamic>>();
        int id = 1;
        public Client()
        {

        }

        public Subject<Response<dynamic>> WsResponse { get => wsResponse; set => wsResponse = value; }

        public dynamic Invoke(String methodName, object[] arguments, Type returnType)
        {
            TaskCompletionSource<dynamic> taskResult = new TaskCompletionSource<dynamic>();
            IObservable<Response<dynamic>> notification = Observable.Create<Response<dynamic>>((result) =>
            {
                wsResponse.Subscribe((res) =>
                {
                    if (id == res.Result)
                    {
                        result.OnNext(res.Result);
                    }

                }, (error) => { });

                return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
            });

            LiveResultPromise<dynamic, dynamic> liveResultPromise = new LiveResultPromise<dynamic, dynamic>(taskResult.Task, notification);
            id++;
            return liveResultPromise;
        }
    }

    class ProxyUtils : IInterceptor
    {
        private Client client;
        public ProxyUtils(Client client)
        {
            this.client = client;
        }

        public void Intercept(IInvocation invocation)
        {
            invocation.ReturnValue = client.Invoke(invocation.Method.Name, invocation.Arguments, invocation.Method.ReturnType);
        }
    }

    class TestCLientExample
    {
        private static MyInterface requestClient;
        static void Main(string[] args)
        {
            Client client = new Client();
            requestClient = new ProxyGenerator().CreateInterfaceProxyWithoutTarget<MyInterface>(new ProxyUtils(client));
            LiveResultPromise<User, User> users = requestClient.getUsers();
            LiveResultPromise<UserContact, UserContact> contact = requestClient.getUserContact("pippo");
            LiveResultPromise<AddressBook, AddressBook> addressBook = requestClient.getAddressBook();

            users.Notification.Subscribe((result) =>
            {
                Console.WriteLine("User Object");
            });

            contact.Notification.Subscribe((result) =>
            {
                Console.WriteLine("UserContact Object");
            });

            addressBook.Notification.Subscribe((result) =>
            {
                Console.WriteLine("AddressBook Object");
            });

            Response<User> res1 = new Response<User>();
            res1.Id = 1;
            res1.Result = new User();

            client.WsResponse.OnNext(res1);

            Response<UserContact> res2 = new Response<UserContact>();
            res2.Id = 2;
            res2.Result = new UserContact();

            client.WsResponse.OnNext(res2);

            Response<AddressBook> res3 = new Response<AddressBook>();
            res3.Id = 3;
            res3.Result = new AddressBook();

            client.WsResponse.OnNext(res3);
        }
    }
}

我的代码有两个问题,首先是这部分

 Response<User> res1 = new Response<User>();
 res1.Id = 1;
 res1.Result = new User();

 client.WsResponse.OnNext(res1);

因为qazxsw poi想要qazxsw poi但是我把qazxsw poi和编译器失败并且错误:无法将client.WsResponse转换为Response<dynamic>

我可以解决这部分代码:

Response<User>

第二个问题是结果:

Response<User>

因为例如Response<dynamic>不能施放到Response<dynamic> res1 = new Response<dynamic>(); res1.Id = 1; res1.Result = new User(); client.WsResponse.OnNext(res1); Response<dynamic> res2 = new Response<dynamic>(); res2.Id = 2; res2.Result = new UserContact(); client.WsResponse.OnNext(res2); Response<dynamic> res3 = new Response<dynamic>(); res3.Id = 3; res3.Result = new AddressBook(); client.WsResponse.OnNext(res3);

我怎么能做类似的事情?

谢谢。

c# generics
1个回答
0
投票

我用这个解决方案解决了我的问题

LiveResultPromise<User, User> users = requestClient.getUsers();
LiveResultPromise<UserContact, UserContact> contact = requestClient.getUserContact("pippo");
LiveResultPromise<AddressBook, AddressBook> addressBook = requestClient.getAddressBook();

我对这部分有疑问,因为我担心我会造成内存泄漏。

LiveResultPromise<dynamic, dynamic>

如果你知道更好的解决方案,请告诉我。

谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.