Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以更改此代码以便可以推断通用方法参数?_C#_Generics - Fatal编程技术网

C# 是否可以更改此代码以便可以推断通用方法参数?

C# 是否可以更改此代码以便可以推断通用方法参数?,c#,generics,C#,Generics,我已经为我的WPF应用程序编写了一个简单的中介程序(它是找到的代码的派生) RemoveObserverWhen方法采用一个谓词,其中T应该是AddObserver方法中指定的消息类型 public interface IDisposeObserver { IDisposeObserver RemoveObserverWhen<T>(Predicate<T> predicate) where T : Message; } 这里的想法是,您可以指

我已经为我的WPF应用程序编写了一个简单的中介程序(它是找到的代码的派生)

RemoveObserverWhen
方法采用一个
谓词,其中
T
应该是
AddObserver
方法中指定的消息类型

public interface IDisposeObserver
{
    IDisposeObserver RemoveObserverWhen<T>(Predicate<T> predicate) 
        where T : Message;
}
这里的想法是,您可以指定在注册观察者本身的同一位置删除观察者的逻辑。然后,Messenger类将在消息处理程序运行后检查谓词,如果谓词的计算结果为true,则同时删除消息处理程序和删除处理程序

每个消息处理程序都可以有任意数量的删除处理程序,因此我将其打包在一个名为
MessageObserver
的类中

public class MessageObserver : IDisposeObserver
{
    private IList<object> disposalHandlers;

    public MessageObserver(object observer)
    {
        Observer = observer;
        disposalHandlers = new List<object>();
    }

    public object Observer { get; private set; }

    public IList<object> DisposalHandlers
    {
        get { return disposalHandlers; }
    }

    public IDisposeObserver RemoveObserverWhen<T>(Predicate<T> predicate) 
        where T : Message
    {
        disposalHandlers.Add(predicate);
        return this;
    }
}
这里的想法是可以返回一个
IDisposeObserver
实例,以便链接方法

所有这些都有效,我的viewModel中有以下代码:

MessengerInstance.AddObserver<LoginMessage>(HandleLogin)
    .RemoveObserverWhen<LoginMessage>(message => message.LoginResult == LoginResult.Successful)
    .RemoveObserverWhen<LoginMessage>(SecondDisposalHandler);
MessengerInstance.AddObserver(HandleLogin)
.RemoveObserverWhen(message=>message.LoginResult==LoginResult.Successful)
.RemoveObserverWhen(第二个DisposalHandler);
我遇到的问题是,只有在调用
RemoveObserver
方法时指定泛型参数(
LoginMessage
)时,这才有效。我希望能够以本文开头描述的方式调用这些方法

我想我需要以某种方式返回一个泛型
IDisposeObserver
,但是如果我做了此更改,那么必须将
MessageObserver
设置为泛型,然后我无法指定约束,因为
Messenger
类是非泛型的

因此,我的问题是,我的代码是否可以更新,以便在调用
RemoveObserverWhen
方法时不必指定消息类型,或者我是否必须使用当前的解决方案?

注意:我知道还有其他的实现,但我这样做是为了帮助我理解c#中的面向对象设计原则和泛型,所以请不要告诉我其他实现的方向

我想我需要以某种方式返回一个泛型IDisposeObserver,但是如果我做了这个更改,那么MessageObserver必须是泛型的,然后我不能指定约束,因为Messenger类是非泛型的

您可能希望有一个非泛型的
MessageObserver
基类,它包含所有类型无关的部分,然后是一个实现泛型
IDisposeObserver
的泛型基类。然后,您可以更改
AddObserver
以返回泛型
IDisposeObserver
,但将字典作为
IDictionary
保存在
Messenger
中。因此,为了明确起见,您必须:

public interface IDisposeObserver<T>
{
    IDisposeObserver<T> RemoveObserverWhen(Predicate<T> predicate) 
        where T : Message;
}

public abstract class MessageObserver { ... }

public class MessageObserver<T> : MessageObserver, IDisposeObserver<T> { ... }
公共接口IDisposeObserver
{
IDisposeObserver RemoveObserverWhen(谓词)
其中T:消息;
}
公共抽象类MessageObserver{…}
公共类MessageObserver:MessageObserver,IDisposeObserver{…}
当您必须执行
IDiposeObserver.RemoveObserverWhen
方法时,问题就会出现——您可能需要将字典列表中的每个项目强制转换为
IObserver
。此时您将知道
T
,并且您将知道您已正确填充了列表

当然,如果这是使用观察者要做的唯一一件事,那么您可以保留一个
IDictionary
,而不用麻烦使用两个不同的
MessageObserver
类。这真的取决于你是否从非泛型中得到任何价值

MessengerInstance.AddObserver<LoginMessage>(HandleLogin)
    .RemoveObserverWhen<LoginMessage>(message => message.LoginResult == LoginResult.Successful)
    .RemoveObserverWhen<LoginMessage>(SecondDisposalHandler);
public interface IDisposeObserver<T>
{
    IDisposeObserver<T> RemoveObserverWhen(Predicate<T> predicate) 
        where T : Message;
}

public abstract class MessageObserver { ... }

public class MessageObserver<T> : MessageObserver, IDisposeObserver<T> { ... }