指定一个接口只能通过引用类型实现C#

如果我用C#声明一个接口,有没有什么办法可以明确地声明实现这个接口的任何类型是一个引用类型?

我想这样做的原因是,无论我将接口用作类型参数,我都不必指定实现类型也必须是引用类型。

我想要实现的例子:

public interface IInterface
{
    void A();
    int B { get; }
}

public class UsingType<T> where T : IInterface
{
    public void DoSomething(T input)
    {
         SomeClass.AnotherRoutine(input);
    }
}

public class SomeClass
{
    public static void AnotherRoutine<T>(T input)
        where T : class
    {
        // Do whatever...
    }
}

由于SomeClass.AnotherRoutine()的参数需要是一个引用类型,所以我会在这里得到一个编译器错误,我调用该方法,这表明我强制T成为引用类型( where T : IInterface, class声明中的where T : IInterface, classUsingType )。 有没有什么办法可以在界面层面实施呢?

public interface IInterface : class

(显然)不起作用,但也许有另一种方式来完成相同的事情?


如果您在接口下传递某些东西,那么即使您有一个实现该接口的值类型,如果转换为接口并且行为类似于引用类型(因为它在参考类型中被装箱),它也会变成方块。

interface IFoo {
    int Value { get; set; }
}

struct Foo : IFoo {
    public int Value { get; set; }
}

当用作值类型时观察效果:

var a = new Foo() { Value = 3 };
var b = a; // copies value
b.Value = 4;
Console.WriteLine( "a has {0}", a.Value ); //output: a has 3
Console.WriteLine( "b has {0}", b.Value ); //output: b has 4

现在看看当你将它转换到界面时会发生什么:

var a = new Foo() { Value = 3 } as IFoo; //boxed
var b = a; // copies reference
b.Value = 4;
Console.WriteLine( "a has {0}", a.Value ); //output: a has 4
Console.WriteLine( "b has {0}", b.Value ); //output: b has 4

因此,结构或类是否实现接口并不重要。 如果转换为接口,然后在接口下传递,则它将表现为引用类型。

编辑 :所以如果这些是你的要求...

对于合同X:

  • 如果结构实现/继承X,则会发出编译错误。
  • X可能不是一个抽象类。
  • 那么,你只是坚持下去,因为那些矛盾对方。

  • 如果结构实现/继承合同,那么得到编译错误的唯一方法是如果它是抽象类。
  • 由于您不能使用抽象类来继承选项,所以您必须使用接口。
  • 执行结构无法实现接口的规则的唯一方法是在运行时期间执行。
  • 使用where T: class, IFoo的约束where T: class, IFoo甚至不会一直工作。 如果我有这个方法(基于上述相同的FooIFoo ):

    static void DoSomething<T>(T foo) where T: class, IFoo {
        foo.Value += 1;
        Console.WriteLine( "foo has {0}", foo.Value );
    }
    

    然后它会在这种情况下发出编译错误:

    var a = new Foo(){ Value = 3 };
    DoSomething(a);
    

    但在这种情况下它会工作得很好:

    var a = new Foo(){ Value = 3} as IFoo; //boxed
    DoSomething(a);
    

    所以,就我而言,使用where T: class, IFoo风格的约束,然后只要结构实现了接口(只要它是盒装的),可能无关紧要。 不过,取决于EF如果通过盒装结构检查什么。 也许它会工作。

    如果它不起作用,至少泛型约束可以让你在那里部分路径,并且你可以检查foo.GetType().IsValueType (引用上面的DoSomething方法)并抛出一个ArgumentException来处理盒装结构的情况。


    http://msdn.microsoft.com/en-us/library/d5x73970.aspx。 看起来你可以指定它是一个“类”,这意味着引用类型。


    我不认为你可以以不幸的方式限制界面。 根据msdn接口可以通过任何类型实现,包括结构体和类:/

    链接地址: http://www.djcxy.com/p/7595.html

    上一篇: Specify that an interface can only be implemented by reference types C#

    下一篇: Base64 in SQLite?