Java类的C#等价物<;?扩展基础>;

本文关键字:扩展 gt lt 类的 等价物 Java | 更新日期: 2023-09-27 18:28:36

我希望能够用C#编写一个类似于在Java中的方法。。。要传入Class对象,该对象是某个超类的子类。。。但我能为C#找到的最好的是:

public void someMethod(Type t) {
  if (t == typeof(SomeType)) ...
}

有没有什么方法可以在方法签名中强制参数必须是类型SomeType或其继承者之一?

我不希望传入所述Type的实例。我想将Type本身作为参数传入。

编辑

这里有一些上下文。

我想创建一个EventManager类,它包含一个Dictionary<SomeEventType, ICollection<EventHandler>>对象和一个将给定的Type映射到EventHandler的方法registerEventHandler(Type t, EventHandler eh)

在Java中,我会这样完成:

private static Map<Class<? extends Event>, Collection<EventHandler>> eventHandlers;
public static void registerListener(Class<? extends Event> event, EventHandler handler) {
  if (eventHandlers.get(event) == null) {
    HashMap<EventHandler> handlers = new HashMap<EventHandler>()
    eventHandlers.put(event, handlers) ...
  }
}

Java类的C#等价物<;?扩展基础>;

您可以使用通用约束。

public void someMethod<T>() where T : SomeType {
    Type myType = typeof(T);
    // do something with myType
}

以下是您想要的用例的实现。

class EventManager {
    public Dictionary<Type, ICollection<EventHandler>> 
        HandlerMap = new Dictionary<Type, ICollection<EventHandler>>();
    public void RegisterEventHandler<TEvent>(EventHandler eh) 
        where TEvent: SomeEventType 
    {
        Type eventType = typeof(TEvent);
        if (!HandlerMap.ContainsKey(eventType)) {
            HandlerMap[eventType] = new List<EventHandler>();
        }
        HandlerMap[eventType].Add(eh);
    }
}

你可以这样称呼它。

var em = new EventManager();
EventHandler eh = null; // or whatever
em.RegisterEventHandler<SpecificEventType>(eh);

您可以通过定义泛型类型来实现行为。

public void SomeMethod<T>(T obj) where T : AbstractClass
{
}

但是没有任何东西可以阻止您仅使用基类作为参数

public void SomeMethod(AbstractClass obj)
{
}

我真的不懂java,但你的意思是这样的?

namespace ConsoleApplication1
{
    class bar
    { public void stuff() { } }
    class foo : bar
    { }
    class doublefoo : bar
    { }
    class Program
    {
        static void Main(string[] args)
        {
            someMethod<foo>();
            someMethod<doublefoo>();
        }
        public static void someMethod<t>() where t: bar, new()
        {
            t myBar = new t();
            myBar.stuff();
        }
    }
}

正如其他人所说,您可以使用泛型类型参数。。。但是,如果您只将值作为Type,并希望将其作为常规参数传入(例如,因为它是以这种方式传递给您的方法的),则没有办法做到这一点。Type在.NET中不是通用的,因此没有将参数约束为代表特定类或其子类的Type的概念,正如没有将字符串参数约束为某个长度或更长的概念一样。

如果在编译时调用方法时确实知道类型,那么根据递归的答案使用泛型类型参数绝对是可行的。