Specify that an interface can only be implemented by reference types C#

If I declare an interface in C#, is there any way I can explicitly declare that any type implementing that interface is a reference type?

The reason I want to do this is so that wherever I use the interface as a type parameter, I don't have to specify that the implementing type also has to be a reference type.

Example of what I want to accomplish:

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...
    }
}

As the argument to SomeClass.AnotherRoutine() is required to be a reference type, I will here get a compiler error where I call the method, suggesting that I force T to be a reference type ( where T : IInterface, class in the declaration of UsingType ). Is there any way I can enforce this already at the interface level?

public interface IInterface : class

doesn't work (obviously) but maybe there's another way to accomplish the same thing?


If you are passing something around under an interface, then even if you have a value type implementing that interface it will become boxed if cast to the interface and behave like a reference type (because it is boxed inside a reference type).

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

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

Observe the effects when used as a value type:

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

Now look what happens when you cast it to the interface:

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

So it doesn't matter whether a struct or class implements the interface. If cast to the interface and then is passed around under the interface, then it will behave as a reference type.

Edit : So if these are your requirements...

For contract X:

  • Throw a compile error if a struct implements/inherits X.
  • X may not be an abstract class.
  • Well, you're simply stuck then, because those contradict each other.

  • The only way to get a compile error if the struct implements/inherits the contract is if it is an abstract class.
  • Since you can't use an abstract class in order to keep inheritance options open, you have to use an interface.
  • The only ways to enforce the rule that a struct cannot implement the interface will be during run-time.
  • Using the constraint where T: class, IFoo wouldn't even work all the time. If I had this method (based on the same Foo and IFoo above):

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

    Then it would throw a compile error under this circumstance:

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

    But it would work just fine under this circumstance:

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

    So as far as I'm concerned, use where T: class, IFoo -style constraint, and then it may not matter if a struct implements the interface as long as it is boxed. Depends on what checking EF does if passed a boxed struct, though. Maybe it will work.

    If it doesn't work, at least the generic constraint gets you part-way there, and you can check foo.GetType().IsValueType (referring to my DoSomething method above) and throw an ArgumentException to handle the case of boxed structs.


    http://msdn.microsoft.com/en-us/library/d5x73970.aspx. Looks like you can specify it's a "class", which means reference type.


    i dont think you can restrict interfaces in that way unfortunatly. According to msdn interfaces can be implemented by any type, both structs and classes :/

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

    上一篇: Xcode静态分析器和copyWithZone

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