Saya memiliki C ++ DLL pihak ketiga yang saya panggil dari C #.
Metodenya statis.
Saya ingin mengabstraksikannya untuk melakukan beberapa pengujian unit jadi saya membuat antarmuka dengan metode statis di dalamnya tetapi sekarang program saya mengalami kesalahan dengan:
Pengubah 'statis' tidak valid untuk item ini
MyMethod cannot be accessed with an instance reference; qualify it with a type name instead
Bagaimana saya bisa mencapai abstraksi ini?
Kode saya terlihat seperti ini
private IInterfaceWithStaticMethods MyInterface;
public MyClass(IInterfaceWithStaticMethods myInterface)
{
this.MyInterface = myInterface;
}
public void MyMethod()
{
MyInterface.StaticMethod();
}
Jawaban:
Anda tidak dapat menentukan anggota statis pada antarmuka di C #. Antarmuka adalah kontrak untuk contoh .
Saya akan merekomendasikan membuat antarmuka seperti Anda saat ini, tetapi tanpa kata kunci statis. Kemudian buat kelas
StaticIInterface
yang mengimplementasikan antarmuka dan memanggil metode C ++ statis. Untuk melakukan pengujian unit, buat kelas lainFakeIInterface
, yang juga mengimplementasikan antarmuka, tetapi melakukan apa yang Anda perlukan untuk menangani pengujian unit Anda.Setelah Anda menentukan 2 kelas ini, Anda dapat membuat kelas yang Anda perlukan untuk lingkungan Anda, dan meneruskannya ke
MyClass
konstruktor.sumber
An interface is a contract, not an implementation.
- itu benar, tetapi sama sekali tidak relevan ( non sequitur ) di sini, karena metode statis bukan bagian dari implementasi itu sendiri - implementasi, menurut definisi, didasarkan pada data , yang, pada gilirannya, tidak dapat diakses untuk anggota statis.An interface type definition can define and implement static methods (see §8.4.3) since static methods are associated with the interface type itself rather than with any value of the type.
- ingatlah bahwastatic
anggota biasanya merupakan metode utilitas .An interface is a contract, not an implementation
itu tidak berguna, terkadang sedikit kontekstualisasi sangat membantu. Dan saya sangat setuju denganstatic method is not a part of implementation itself
, metode statis memiliki implementasi, mereka menjadi bagian dari implementasi hanya jika digunakan sebagai implementasi dalam implementasi metode lain. Bagaimanapun kamus saya didasarkan pada apa yang dipelajari, setahu saya, terminologi sangat bervariasi juga tergantung pada bahasa pemrograman. Metode statis tidak dapat menjadi antarmuka karena hanya ada 1 implementasi.IPerson
kontrak yang menyatakan bahwaGetCountry
akan memberikan nama negara asal orang tersebut ...FrenchPerson
semua entitas akan mengatakan "Prancis" danGermanPerson
semua akan mengatakan "Jerman", juga berguna ketika berbagai jenis entitas memiliki Tabel (Data) yang sama, seperti MS Azure satu, katakanlahConnection
,Post
danComment
disimpan diUsers
AzureTable, sehingga entitas pohon memiliki info bersama,IUsers
dapat memilikiGetTableName
metode statis ...Antarmuka tidak boleh memiliki anggota statis dan metode statis tidak dapat digunakan sebagai implementasi metode antarmuka.
Yang dapat Anda lakukan adalah menggunakan implementasi antarmuka eksplisit:
public interface IMyInterface { void MyMethod(); } public class MyClass : IMyInterface { static void MyMethod() { } void IMyInterface.MyMethod() { MyClass.MyMethod(); } }
Alternatifnya, Anda dapat dengan mudah menggunakan metode non-statis, bahkan jika mereka tidak mengakses anggota khusus instance.
sumber
Anggota statis benar-benar legal di CLR, hanya saja bukan C #.
Anda dapat menerapkan beberapa perekat di IL untuk menghubungkan detail implementasi.
Tidak yakin apakah kompilator C # akan mengizinkan pemanggilan mereka?
Lihat: 8.9.4 Definisi tipe antarmuka ECMA-335.
sumber
CLS Rule 19: CLS-compliant interfaces shall not define static methods, nor shall they define fields.
selanjutnya dikatakan bahwa tidak masalah bagi konsumen yang patuh CLS untuk menolak jenis antarmuka ini. Saya mencoba sekitar setahun yang lalu untuk memanggil metode statis pada sebuah antarmuka dan kompiler C # tidak akan mengkompilasinya.Common Language Specification (CLS) is a set of basic language features that .Net Languages needed.... When there is a situation to communicate Objects written in different .Net Complaint languages , those objects must expose the features that are common to all the languages.
Masuk akal bahwa jika CLS adalah tentang interoperabilitas di berbagai bahasa .NET, dan C # tidak mengizinkan anggota statis pada antarmuka, maka CLS akan melarang mereka juga, untuk memastikan perpustakaan di bahasa .NET lainnya dapat dipanggil dari C #.Anda dapat mendefinisikan metode statis di c # 8 tetapi Anda harus mendeklarasikan isi default untuk itu.
public interface IMyInterface { static string GetHello() => "Default Hello from interface" ; static void WriteWorld() => Console.WriteLine("Writing World from interface"); }
atau jika Anda tidak ingin memiliki isi default, cukup berikan pengecualian:
public interface IMyInterface { static string GetHello() => throw new NotImplementedException() ; static void WriteWorld() => throw new NotImplementedException(); }
sumber
Anda bisa memintanya dengan refleksi:
MyInterface.GetType().InvokeMember("StaticMethod", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null);
sumber
C # "Sepuluh" akan mengizinkan anggota statis pada antarmuka , bersama dengan peran. Ini adalah langkah maju yang besar, ini akan memungkinkan operator generik kelebihan beban juga, tanpa menggunakan refleksi. Berikut ini cuplikan contoh cara kerjanya, menggunakan contoh monoid klasik, yang hanya jargon untuk mengatakan "sesuatu yang bisa ditambahkan". Diambil langsung dari Mads Torgersen: C # into the Future :
interface IMonoid<T> { static T Zero { get; } static T operator +(T t1, T t2); } public static T AddAll<T>(T[] ts) where T : IMonoid<T> { T result = T.Zero; foreach (T t in ts) { result += t; } return result; } role IntAddMonoid extends int : IMonoid<int> { public static int Zero => 0; } IntAddMonoid[] values = new int[] {1, 2, 4, 8, 16, 32}; int sixtyThree = AddAll<IntAddMonoid>(values); // == 63
Sumber daya tambahan:
Jeremy Bytes: C # 8 antarmuka anggota statis
EDIT
Posting ini awalnya menyatakan antarmuka anggota statis akan ditambahkan di C # 8.0 , yang tidak benar, saya salah menafsirkan kata-kata Mads Torgersen dalam video. Panduan resmi C # 8.0 belum berbicara tentang anggota antarmuka statis, tetapi jelas mereka telah mengerjakannya cukup lama sekarang.
sumber
Tentang mengapa Anda tidak dapat memiliki metode statis pada antarmuka: Mengapa C # Tidak Mengizinkan Metode Statis untuk Menerapkan Antarmuka?
Namun, saya menyarankan untuk menghapus metode statis demi metode instance. Jika itu tidak memungkinkan, Anda dapat menggabungkan panggilan metode statis di dalam metode instance, lalu Anda dapat membuat antarmuka untuk itu dan menjalankan pengujian unit dari itu.
yaitu
public static class MyStaticClass { public static void MyStaticMethod() {...} } public interface IStaticWrapper { void MyMethod(); } public class MyClass : IStaticWrapper { public void MyMethod() { MyStaticClass.MyStaticMethod(); } }
sumber
C # 8 Memungkinkan Anggota Statis di Antarmuka
antarmuka (Referensi C #)
Misalnya
public interface IGetSomething { public static string Something = "something"; } var something = IGetSomething.Something;
sumber