【问题标题】:How to create an optional generic method in an interface?如何在接口中创建可选的泛型方法?
【发布时间】:2021-06-18 13:21:56
【问题描述】:

我的问题太简单了,我有一个Interface,其中包含一个method

界面:

public interface IAbstract
{
    void DoSomething();
}

我有两个类会在接口中包含相同的方法,所以我想让他们(Classes)实现接口。

问题: 唯一的问题是在其中一个类中该方法将正常实现,但在另一个类中该方法将作为泛型方法实现

我的代码想法:

头等舱:

public class ClassOne:IAbstract
{
    public void DoSomething()
    {
        throw new System.NotImplementedException();
    }
} 

二等:

public class ClassTwo:IAbstract
{
    public void DoSomething<int>()
    {
        throw new System.NotImplementedException();
    }
}

我知道这给了我一个错误,但我的问题有没有什么办法可以在不创建分离接口的情况下做我认为的事情?

【问题讨论】:

  • 不,你不能,因为接口IAbstract 的用户不可能知道它甚至需要一个通用参数。不清楚你要做什么,好像ClassTwo 已经知道它需要是一个int 为什么它需要一个通用参数?或者您可能想在ClassTwo 上声明泛型参数?

标签: c# generics interface abstraction


【解决方案1】:

您有多种设计选项可以满足您的需求。

    static void Main(string[] args)
    {
        var one = new ClassOne();
        one.DoSomething(); 
        var two = new ClassTwo();
        two.DoSomething();
        two.DoSomething<int>();
        var three = new ClassThree<int>();
        three.DoSomething();
        three.DoSomething(100);
    }

和代码

public interface IAbstract
{
    void DoSomething();
}
public interface IAbstract<in T> : IAbstract
{
    void DoSomething(T arg);
}

public class ClassOne : IAbstract
{
    public void DoSomething()
    {
        Debug.WriteLine("DoSomething()");
    }
}
public class ClassTwo : IAbstract
{
    public void DoSomething()
    {
        Debug.WriteLine("DoSomething()");
    }
    public void DoSomething<T>()
    {
        Debug.WriteLine("DoSomething<T>()");
    }
}
public class ClassThree<T> : IAbstract where T : new()         
{
    public void DoSomething()
    {
        Debug.WriteLine("DoSomething()");
    }
    public void DoSomething(T arg)
    {
        Debug.WriteLine("DoSomething(T arg)");
    }
}

【讨论】:

    【解决方案2】:

    你应该这样做:

    public interface IAbstractRoot<T>
    {
        void DoSomthing<TT>() where TT : T;
    }
    
    public abstract class IAbstractRoot : IAbstractRoot<object>
    {
        public void DoSomthing<TT>()
        {
            DoSomthing();
        }
    
        public abstract void DoSomthing();
    }
    

    孩子应该是这样的:

    public class Child1 : IAbstractRoot<int>
    {
        void IAbstractRoot<int>.DoSomthing<TT>()
        {
            throw new System.NotImplementedException();
        }
    }
    
    public class Child2 : IAbstractRoot
    {
        public override void DoSomthing()
        {
    
        }
    }
    

    【讨论】:

    • 也许这只是一个模型,但如果我不指出名为 IAbstractRoot 的抽象类,我的强迫症会杀了我。
    • 亲爱的,别无他法。接口的实现只能是 GENERIC 或 NonGeneric。 “不是两者”
    • 没错,但我的意思是“I”前缀是一个接口,而不是抽象类。
    • 是的,你是对的。你不应该命名它(抽象)!从所有界面中删除“I”和“Abstract”关键字。这将是最好的。例如:将 IAbstractRoot 接口名称更改为 -> IRoot。并将 IAbstractRoot 类更改为 AbstractRoot。
    【解决方案3】:

    只需为接口分配一个通用参数,然后在实现时提供一个具体类型。为了保持它的通用性,只需为 b 类提供一个泛型,这样您就可以将它传递给接口,就像这样..

    void Main()
    {
        var a = new a();
        var b = new b<string>();
        
        a.DoSomething(1);
        b.DoSomething("Here is a string");
    }
    
    public interface IAbstract<in T>
    {
        void DoSomething(T param1);
    }
    
    public class a : IAbstract<int>
    {
        public void DoSomething(int param1)
        {
            Console.WriteLine($"I am specificly an int {param1}");
        }
    }
    
    public class b<T> : IAbstract<T>
    {
        public void DoSomething(T param1)
        {
            Console.WriteLine($"I am a generic something {param1}");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2020-03-13
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多